首页 > 数据库 >Redis设计思路总结

Redis设计思路总结

时间:2024-07-18 23:51:17浏览次数:13  
标签:总结 AOF 同步 hash Redis 内存 RDB 思路

本文从网络模型、数据结构和内存管理、持久化和多机协作四个角度对redis的设计思路进行分析。

一.网络模型

Redis是典型的基于Reactor的事件驱动模型,单进程单线程,高效的框架总是类似的。网络模型与spp的异步模型几乎一致。

Redis流程上整体分为接受请求处理器、响应处理器和应答处理器三个同步模块,每一个请求都是要经历这三个部分。

Redis集成了libevent/epoll/kqueue/select等多种事件管理机制,可以根据操作系统版本自由选择合适的管理机制,其中libevent是最优选择的机制。

Redis的网络模型有着所有事件驱动模型的优点,高效低耗。但是面对耗时较长的操作的时候,同样无法处理请求,只能等到事件处理完毕才能响应。所以了解清楚网络模型有助于在业务中扬长避短,减少长耗时的请求,尽可能多一些简单的短耗时请求发挥异步模型的最大的威力。

二.数据结构和内存管理

1.字符串

1.1 内存管理方式

动态内存管理方式,动态方式最大的好处就是能够较为充分的利用内存空间,减少内存碎片化,与此同时带来的劣势就是容易引起频繁的内存抖动,通常采用“空间预分配”和“惰性空间释放”两种优化策略来减少内存抖动,redis也不例外。

每次修改字符串内容时,首先检查内存空间是否符合要求,否则就扩大2倍或者按M增长;减少字符串内容时,内存并不会立刻回收,而是按需回收。

关于内存管理的优化,最基本的出发点就是浪费一点空间还是牺牲一些时间的权衡,像STL、tcmalloc、protobuf3的arena机制等采用的核心思路都是“预分配迟回收”,Redis也是一样的。

1.2 二进制安全

判断字符串结束与否的标识是len字段,而不是C语言的’\0’,因此是二进制安全的。

放心的将pb序列化后的二进制字符串存入redis。

简而言之,通过redis的简单封装,redis的字符串的操作更加方便,性能更友好,并且屏蔽了C语言字符串的一些需要用户关心的问题。

2.字典(哈希)

字典的底层一定是hash,涉及到hash一定会涉及到hash算法、冲突的解决方法和hash表扩容和缩容。

2.1 hash算法

  Redis使用的就是常用的Murmurhash2,Murmurhash算法能够给出在任意输入序列下的散列分布性,并且计算速度很快。之前做共享内存的Local-Cache的需求时也正是利用了Murmurhash的优势,解决了原有结构的hash函数散列分布性差的问题。

2.2 hash冲突解决方法

链地址法解决hash冲突,通用解决方案没什么特殊的。多说一句,如果选用链地址解决冲突,那么势必要有一个散列性非常好的hash函数,否则hash的性能将会大大折扣。Redis选用了Murmurhash,所以可以放心大胆的采用链地址方案。

3.整数集合

变长整数存储,整数分为16/32/64三个变长尺度,根据存入的数据所属的类型,进行规划。

每次插入新元素都有可能导致尺度升级(例如由16位涨到32位),因此插入整数的时间复杂度为O(n)。这里也是一个权衡,内存空间和时间的一个折中,尽可能节省内存。

4.跳跃表

Redis的skilplist和普通的skiplist没什么不同,都是冗余数据实现的从粗到细的多层次链表,Redis中应用跳表的地方不多,常见的就是有序集合。

5.链表

Redis的链表是双向非循环链表,拥有表头和表尾指针,对于首尾的操作时间复杂度是O(1),查找时间复杂度O(n),插入时间复杂度O(1)。

三.AOF和RDB持久化

AOF持久化日志,RDB持久化实体数据,AOF优先级大于RDB。

1.AOF持久化

机制:通过定时事件将aof缓冲区内的数据定时写到磁盘上。

2.AOF重写

为了减少AOF大小,Redis提供了AOF重写功能,这个重写功能做的工作就是创建一个新AOF文件代替老的AOF,并且这个新的AOF文件没有一条冗余指令。(例如对list先插入A/B/C,后删除B/C,再插入D共6条指令,最终状态为A/D,只需1条指令就可以)

实现原理就是读现有数据库的状态,根据状态反推指令,跟之前的AOF无关。同样,为了避免长时间耗时,重写工作放在子进程进行。

3.RDB持久化

SAVE和BGSAVE两个命令都是用于生成RDB文件,区别在于BGSAVE会fork出一个子进程单独进行,不影响Redis处理正常请求。定时和定次数后进行持久化操作。

简而言之,RDB的过程其实是比较简单的,满足条件后直接去写RDB文件就结束了。

四.多机和集群

1.主从服务器

避免单点是所有服务的通用问题,Redis也不例外。解决单点就要有备机,有备机就要解决固有的数据同步问题。

1.1 sync——原始版主从同步

Redis最初的同步做法是sync指令,通过sync每次都会全量数据,显然每次都全量复制的设计比较消耗资源。改进思路也是常规逻辑,第一次全量,剩下的增量,这就是现在的psync指令的活。

1.2 psync

部分重同步实现的技术手段是“偏移序号+积压缓冲区”,具体做法如下:

(1)主从分别维护一个seq,主每次完成一个请求便seq+1,从每同步完后更新自己seq;

(2)从每次打算同步时都是携带着自己的seq到主,主将自身的seq与从做差结果与积压缓冲区大小比较,如果小于积压缓冲区大小,直接从积压缓冲区取相应的操作进行部分重同步;

(3)否则说明积压缓冲区不能够cover掉主从不一致的数据,进行全量同步。

本质做法用空间换时间,显然在这里牺牲部分空间换回高效的部分重同步,收益比很大。

2.Sentinel

本质:多主从服务器的Redis系统,多台主从上加了管理监控,以保证系统高可用性。

标签:总结,AOF,同步,hash,Redis,内存,RDB,思路
From: https://www.cnblogs.com/beatle-go/p/18310617

相关文章

  • Spring事务失效场景详细总结(下)
    1.错误的传播特性        其实,我们在使用@Transactional注解时,是可以指定propagation参数的。 该参数的作用是指定事务的传播特性,spring目前支持7种传播特性:REQUIRED 如果当前上下文中存在事务,那么加入该事务,如果不存在事务,创建一个事务,这是默认的传播属性值。......
  • Java基础常见面试题总结(下)
    目录异常Exception和Error有什么区别?Throwable类常用方法有哪些?  try-catch-finally如何使用?finally代码块中的代码一定会执行吗? 异常使用有哪些需要注意的地方? 泛型什么是泛型?有什么作用?泛型的使用类型有哪几种?项目中哪里使用到了泛型?反射反射是什么? ......
  • 蓝桥杯单片学习总结(Day12 串口通讯实验)
    实验现象:        通过串口调试助手发送数字1~8,板子上面的对应指示灯亮。注意此处发送应选择文本模式发送。 实例代码:#include<STC15F2K60S2.H>#defineBUAD 9600//所需波特率、#defineSYSTEMCLOCK 11059200L//系统时钟频率,L表示该数据为长整型voiduart_......
  • 红队信息搜集总结
    红队信息搜集总结简介信息搜集在渗透测试or红蓝对抗中是前期的主要工作,有说法是信息搜集做的时间越长,打起来就越简单。一般攻击者在进行渗透前都要列一个checklist,列出要搜集/攻击的信息/漏洞,一份简单的ckecklist如下所示子域名路径端口旁站C段中间件真实IP系统类型、......
  • [Redis]字典详解
    字典是Redis服务器中出现最为频繁的复合型数据结构,除了hash结构的数据会用到字典(dict)外,整个Redis数据库的所有key和value也组成了一个全局字典还有带过期时间的key集合也是一个字典。zset集合中存储value和score值的映射关系也是通过字典结构实现的。structR......
  • [Redis]双写一致性
    经典缓存模式旁路缓存读数据首先读缓存,如果缓存中有这个数据,直接返回如果缓存中没有这个数据,去读数据库,如果数据库中有这个数据,先把这个数据更新到缓存,再返回数据如果数据库也没有这个数据,返回无数据写数据先更新数据库,再删除缓存读写穿透缓存这个模式在用户......
  • STL学习总结
    常用容器string容器基本概念string是C++风格的字符串,本质上是一个类。其内部封装了char*。成员函数主要有find,copy,delete,replace,insert构造函数string();//生成空stringstring(constchar*s);//以字符串s初始化string(conststring&str);//以string对......
  • 第一章-化学计算基础总结
    字母:\(n:\)物质的量(单位:摩尔\(mol\))\(N:\)微粒数\(N_A:\)阿伏伽德罗常数\(m:\)质量(单位:克\(g\))\(M:\)摩尔质量(单位:克/摩尔\(g/mol\))\(p:\)压强(单位:帕\(Pa\))\(V:\)体积(单位:立方米\(m^3\))\(T:\)温度(单位:开尔文\(K\))\(R:\)气体常数\(x:\)物质的量分数\(c:......
  • redis
    1.redis的数据类型简介:Redis是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。它支持多种类型的数据结构,如字符串(strings),散列(hashes),列表(lists),集合(sets),有序集合(sortedsets)与范围查询,bitmaps,hyperloglogs和地理空间(geospatial)索引半径......
  • yearning订阅webhook发送到企业微信个人或群(思路)
    yearning的默认webhook格式支持钉钉,默认格式不支持企业微信。本文的目的是讲工单流程节点变更通知到企业微信个人或群。本文假设读者已具备以下技能1、pythonflask2、企业微信接口对接1)到群比较简单,直接转到指定URL即可2)到个人,需要脚本内换access_token,并且需要有效......