Redis和Memcached比较:
https://www.cnblogs.com/JavaBlackHole/p/7726195.html
https://blog.csdn.net/lch_2016/article/details/81078243
为什么Redis是多线程的(我觉得讲的很好):
https://blog.csdn.net/world6/article/details/79381682
Redis集群分片原理:
https://blog.csdn.net/wang123459/article/details/79601149
分片:
1)客户端实现 不使用一致性hash而是sharding (一致性hash:https://zhuanlan.zhihu.com/p/34985026)
2)服务端实现 redis3.0
3)代理服务器实现 Twemproxy
集群成员管理:
cluster>node>slot>key
节点会定期给其他所有的节点发送Ping,cluster-node-timeout(可配置,秒级)时间内没有收到对方的回复,则单方面认为对端节点宕机,将该节点标为PFAIL状态。通过节点之间交换信息收集到quorum个节点都认为这个节点为PFAIL,则将该节点标记为FAIL,并且将其发送给其他所有节点,其他所有节点收到后立即认为该节点宕机。从这里可以看出,主宕机后,至少cluster-node-timeout时间内该主所负责的Slot的读写服务不可用。
一致性保证:
Redis cluster并不能保证数据的强一致性. 这意味这在实际中集群在特定的条件下可能会丢失写操作。
第一个原因是因为集群是用了异步复制. 写操作过程:
1)客户端向主节点B写入一条命令。
2)主节点B向客户端回复命令状态。
3)主节点将写操作复制给他得从节点 B1, B2 和 B3。
主节点对命令的复制工作发生在返回命令回复之后, 因为如果每次处理命令请求都需要等待复制操作完成的话, 那么主节点处理命令请求的速度将极大地降低 —— 我们必须在性能和一致性之间做出权衡。
Redis 集群另外一种可能会丢失命令的情况是集群出现了网络分区, 并且一个客户端与至少包括一个主节点在内的少数实例被孤立。
举个例子 假设集群包含 A 、 B 、 C 、 A1 、 B1 、 C1 六个节点, 其中 A 、B 、C 为主节点, A1 、B1 、C1 为A,B,C的从节点, 还有一个客户端 Z1 。假设集群中发生网络分区,那么集群可能会分为两方,大部分的一方包含节点 A 、C 、A1 、B1 和 C1 ,小部分的一方则包含节点 B 和客户端 Z1 .
Z1仍然能够向主节点B中写入, 如果网络分区发生时间较短,那么集群将会继续正常运作,如果分区的时间足够让大部分的一方将B1选举为新的master,那么Z1写入B中得数据便丢失了.
注意, 在网络分区出现期间, 客户端 Z1 可以向主节点 B 发送写命令的最大时间是有限制的, 这一时间限制称为节点超时时间(node timeout), 是 Redis 集群的一个重要的配置选项。
分布式锁:
保证数据的最终一致性
单机Redis实现分布式锁:https://wudashan.cn/2017/10/23/Redis-Distributed-Lock-Implement/
集群Redis实现分布式锁:https://www.jianshu.com/p/fb9993d1b27e Redisson
为什么执行eval()方法可以确保原子性,源于Redis的特性:
简单来说,就是在eval命令执行Lua代码的时候,Lua代码将被当成一个命令去执行,并且直到eval命令执行完成,Redis才会执行其他命令。
高可用性(HA):
https://segmentfault.com/a/1190000002680804
Redis-Sentinel