分类 redis 下的文章
redis HyperLoglog
redis分布式锁
先说说redis分布式锁的原理。
加锁:setnx一个key,返回1说明加锁成功,0说明锁已经存在。
解锁:del该key。
原理说完了,再讨论特殊情况。
1.在set之后,如果客户端挂了,锁会一直存在,导致死锁。
那有人会说,用expire。
但是两个命令无法保证原子性。
还好,redis从2.6.12开始,set命令支持一系列参数来修改。
set key value EX seconds NX
2.对单机来说没问题,但是在集群环境下还是有问题。redis集群数据同步是异步的,当master节点获得锁后崩溃了,数据还没同步到其他master节点,那么新的master还是有可能获得锁。
如何解决单节点故障问题,redis提供了redlock算法。
3.加锁讨论完,再讨论解锁。解锁要保证删除的是自己设置的锁。正常逻辑是先get,判断锁是否存在,存在则删除。但是有个问题,如果程序在加锁后执行时间很长且锁过期时间较短,get到锁后锁自动过期了,并且别的客户端加锁成功,若此时删除就删了别人的锁。
所以,在get和del之间不能有其他命令,redis做不到,可以通过lua实现
'if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end'
因为lua执行可以保证原子性。
lua执行多条命令,由于redis是单线程,中间不会有穿插其他命令。
如果不用lua,执行多条命令可能中间有别得命令执行。
集群模式
上面说的是单机模式下的,如果是集群模式下,刚获得锁主节点就挂了,锁还没有同步到从节点,此时从节点切换为主节点,此时已经没有锁,任何连接都可以设置锁了,但问题是之前的连接还未执行释放锁,若此时执行释放锁操作则会释放别人的锁,这就会出现问题。丧失锁的安全性。针对这个问题,成熟的方案是redlock算法。
redlock算法
redis 集群 cluster
集群是redis分布式数据库方案,通过分片进行数据共享,并提供复制和故障转移功能。
关键技术点:集群节点、槽指派、命令执行、重新分片、转向、故障转移、消息。
redis 对象与编码
redis使用的数据结构包括:简单动态字符串(sds)、双端链表、字典、压缩列表、整数集合等。但是并没有直接使用,而是在此基础上封装了一套对象系统,5种类型的对象:字符串对象、哈希对象、列表对象、集合对象、有序集合对象。
redis 链表
链表在列表对象、发布订阅、慢查询、监视器等功能都出现过。redis服务器本身还用链表保存多个客户端的状态信息,以及构建客户端输出缓冲区(output buffer)。
redis 列表对象
列表对象编码可以是ziplist 或者 linkedlist。 当列表对象使用ziplist的条件:
- 列表对象保存的所有字符串元素都小于64字节;
- 列表对象保存的元素个数小于512个。
redis 字符串对象
redis 字典
redis 跳跃表
跳跃表
跳跃表skiplist 是一种有序数据结构,通过在每个节点维持多个指向其他节点的指针,从而达到快速访问的目的。
跳跃表可以在O(logn)、最坏O(N)时间复杂度下查找节点,还有顺序性操作批量处理节点。