集群
主从架构
- 配置 replicaof
- 只能提供简单的备份。无法自动选举
- 基于rbd快照去做异步复制
- 主从复制风暴,多个从几点从主节点复制数据
哨兵架构
- 每个哨兵都是一个redis实例
- 当半数以上的哨兵节点发现某个主节点挂了,就会进行自动选举
- 只有高可用的功能,但是没有分片的功能
集群架构
- 16384个槽位进行分片,2的14次方用bitmap表示需要2k。(为啥不用16次方即8k的槽位,因为集群中的节点需要互相通信,各个节点会把自己负责的槽位信息用2k大小的bitmap发送给其他节点,2k相对于8k在满足期望的条件下减少了网络通信的压力)
- 客户端使用CRC16算法定位到指定的槽位
- 客户端本地会存储一份服务器的槽位映射表,如果错误的话,服务端会返回moved错误重定向,客户端进行重新访问并更新本地映射表。
- min-replicas-to-write 3 至少有多少节点写入成功,才返回给客户端成功,可有效防止脑裂问题
- cluster-require-full-coverage yes 集群是否完整才能对外提供服务,为no时,表示当负责一个插槽的主库下线且没有相应的从库进行故障恢复时,集群仍然可用。如果为yes则表示集群不可用。
- 集群批量操作,例如mset key1 val1 key2 val2。redis集群默认只支持所有的key落在同一个slot的情况,如果有多个key一定要使用mset命令在集群上操作,则可以在key的前面加上{xx},这样参数数据分片hash计算的只会是大括号里面的值,这样能确保不同的key落在同一个slot里面去,示例:mset {user1}:name xx {user1}:age 18
高性能
redis是单线程吗
redis的单线程主要是指redis的网络io和键值对读取是由一个线程来完成的,这也是redis对外提供键值对服务的主要流程。但是redis的其他功能,比如持久化、异步删除、集群数据同步等,其实都是额外的线程完成的。最新版本中网络io也可以由多个线程处理
redis单线程为什么还能那么快
- 基于内存,所有运算都是内存级别的运算
- 单线程避免了多线程切换性能损耗问题,所以应该避免那种耗时的操作如keys *,可以用scan+游标cursor代替keys命令,但是这个命令会有不精确的问题
- redis采用epoll实现io多路复用。将连接信息和事件信息放入队列中。由事件分配器将事件发给事件处理器
- 高效的数据结构,根据不同的类型设计不同的存储结构,最大程度的节省内存,提高内存的使用率。