redis
2020-10-20 21:17:11 0 举报
AI智能生成
登录查看完整内容
Redis核心技术
作者其他创作
大纲/内容
master-slave架构
主从同步相关内容
1、复制的完整流程(1)slave node启动,仅仅保存master node的信息,包括master node的host和ip,但是复制流程没开始master host和ip是从哪儿来的,redis.conf里面的slaveof配置的(2)slave node内部有个定时任务,每秒检查是否有新的master node要连接和复制,如果发现,就跟master node建立socket网络连接(3)slave node发送ping命令给master node(4)口令认证,如果master设置了requirepass,那么salve node必须发送masterauth的口令过去进行认证(5)master node第一次执行全量复制,将所有数据发给slave node(6)master node后续持续将写命令,异步复制给slave node2、数据同步相关的核心机制指的就是第一次slave连接msater的时候,执行的全量复制,那个过程里面你的一些细节的机制(1)master和slave都会维护一个offsetmaster会在自身不断累加offset,slave也会在自身不断累加offsetslave每秒都会上报自己的offset给master,同时master也会保存每个slave的offset这个倒不是说特定就用在全量复制的,主要是master和slave都要知道各自的数据的offset,才能知道互相之间的数据不一致的情况(2)backlogmaster node有一个backlog,默认是1MB大小master node给slave node复制数据时,也会将数据在backlog中同步写一份backlog主要是用来做全量复制中断候的增量复制的(3)master run idinfo server,可以看到master run id如果根据host+ip定位master node,是不靠谱的,如果master node重启或者数据出现了变化,那么slave node应该根据不同的run id区分,run id不同就做全量复制如果需要不更改run id重启redis,可以使用redis-cli debug reload命令(4)psync从节点使用psync从master node进行复制,psync runid offsetmaster node会根据自身的情况返回响应信息,可能是FULLRESYNC runid offset触发全量复制,可能是CONTINUE触发增量复制3、全量复制(1)master执行bgsave,在本地生成一份rdb快照文件(2)master node将rdb快照文件发送给salve node,如果rdb复制时间超过60秒(repl-timeout),那么slave node就会认为复制失败,可以适当调节大这个参数(3)对于千兆网卡的机器,一般每秒传输100MB,6G文件,很可能超过60s(4)master node在生成rdb时,会将所有新的写命令缓存在内存中,在salve node保存了rdb之后,再将新的写命令复制给salve node(5)client-output-buffer-limit slave 256MB 64MB 60,如果在复制期间,内存缓冲区持续消耗超过64MB,或者一次性超过256MB,那么停止复制,复制失败(6)slave node接收到rdb之后,清空自己的旧数据,然后重新加载rdb到自己的内存中,同时基于旧的数据版本对外提供服务(7)如果slave node开启了AOF,那么会立即执行BGREWRITEAOF,重写AOFrdb生成、rdb通过网络拷贝、slave旧数据的清理、slave aof rewrite,很耗费时间如果复制的数据量在4G~6G之间,那么很可能全量复制时间消耗到1分半到2分钟4、增量复制(1)如果全量复制过程中,master-slave网络连接断掉,那么salve重新连接master时,会触发增量复制(2)master直接从自己的backlog中获取部分丢失的数据,发送给slave node,默认backlog就是1MB(3)msater就是根据slave发送的psync中的offset来从backlog中获取数据的5、heartbeat主从节点互相都会发送heartbeat信息master默认每隔10秒发送一次heartbeat,salve node每隔1秒发送一个heartbeat6、异步复制master每次接收到写命令之后,现在内部写入数据,然后异步发送给slave node
单线程问题
redis为什么使用单线程
redis单线程为什么快?
操作读取、写入都是在内存中完成的多路复用机制
redis是单线程的吗?
redis并不是严格意义上的单线程。网络Io和数据的读写是由单线程来完成的,集群数据同步、数据持久化。数据异步删除是由额外线程来完成的。
多路复用
Linux中的IO多路复用机制就是指,一个线程可以处理多个IO流操作。也就是select/epoll该机制允许内核中,同时存在多个监听套接字和已连接套接字为了在请求到达时能通知到 Redis 线程,select/epoll 提供了基于事件的回调机制,即针对不同事件的发生,调用相应的处理函数。
Cluster集群
哈希槽 Hash Solt
节点分配哈希槽
redis
灾备
RDB
策略
默认 save 900 1 十五分钟有一条写入即生成一次rdb save 300 10 五分钟有十条写入即生成一次rdb save 60 10000 一分钟有一万次写入生成一次rbd
生成RDB文件命令
Save 在主线程中执行,会阻塞线程
写时复制COW(Copy on write)
潜在风险
AOF
默认关闭 appendonly 设置为yes 打开always:每次写入一条数据,立即把这个数据对应的日志写入到fsync到磁盘上去 性能很差一般不推荐使用everysec:每秒将os cache中的数据fsync到磁盘 这个是最常用的no:仅仅将数据写入到os cache就不管了,后面os自己将数据刷到磁盘上。因为不可控 用的比较少
日志
AOF日志写入时为了速度够快不会进行语法检查为了保证语法的正确性使用写后日志也就是redis做完对应的操作后,再写入日志中.这样的好处就是 1.速度快2不会阻塞当前写操作
数据结构
哈希表
哈希桶中存放的是具体指的指针
哈希冲突是不可避免的,解决哈希冲突的方法是使用链式哈希,就是同一个哈希桶的数据使用链表来保存
为了使 rehash 操作更高效,Redis 默认使用了两个全局哈希表:哈希表 1 和哈希表 2。一开始,当你刚插入数据时,默认使用哈希表 1,此时的哈希表 2 并没有被分配空间。随着数据逐步增多,Redis 开始执行 rehash,这个过程分为三步:
给哈希表 2 分配更大的空间,例如是当前哈希表 1 大小的两倍;
把哈希表 1 中的数据重新映射并拷贝到哈希表 2 中;
释放哈希表 1 的空间。
其中第二部看似简单,但是如果数据量够大的话势必会造成redis线程阻塞.无法服务其他请求.为了解决这个问题,使用的方法是渐进式redash.在渐进式 rehash 进行期间, 字典的删除(delete)、查找(find)、更新(update)等操作会在两个哈希表上进行: 比如说, 要在字典里面查找一个键的话, 程序会先在 ht[0] 里面进行查找, 如果没找到的话, 就会继续到 ht[1] 里面进行查找, 诸如此类。另外, 在渐进式 rehash 执行期间, 新添加到字典的键值对一律会被保存到 ht[1] 里面, 而 ht[0] 则不再进行任何添加操作: 这一措施保证了 ht[0] 包含的键值对数量会只减不增, 并随着 rehash 操作的执行而最终变成空表。
压缩列表
压缩列表类似于数组,数组中的每一个元素都对应保存一个数据,和数组不同的时在数组头部保存三个值zlbytes(列表的长度)、zltail(列表尾部的偏移量) 和 zllen(列表中entity的个数)。因此如果我们要查找一个和最后一个元素时间复杂度戳O(1),如果要查找其他数据就需要遍历了O(n)
跳表
跳表类似于链表,和链表不同的是在链表的基础上增加了多级索引,根据索引可以快速定位到数据
整数数组和双向链表
都是需要遍历查找时间复杂度O(n)
哨兵
监控
监控是指哨兵周期性的给所有主从库发送PING命令检测他们是否在运行
选主
筛选:筛选掉一些之前总是和主库断链的从库。down-after-milliseconds * 10 即主从库断连的最大连接超时时间 断联10次就说明从库网络不好
打分第一轮 从库优先级最高的作为新主库 配置项:slave-priority 设置从库的优先级
打分第二轮 和旧主库同步程度最接近的从库得分高, slave_repl_offset 需要最接近 master_repl_offset
打分第三轮 每个实例都会有一个 ID,这个 ID 就类似于这里的从库的编号。目前,Redis 在选主库时,有一个默认的规定:在优先级和复制进度都相同的情况下,ID 号最小的从库得分最高,会被选为新主库。
通知
哨兵会把新的主库连接信息发送给其他从库,让他们执行replicaof命令和新主库建立连接
收藏
收藏
0 条评论
回复 删除
下一页