redis cluster、配置文件介绍等

1.在模糊匹配redis中的key时建议使用scan,而不是使用keys,因为当redis中存储的key-value非常大时,keys会查询所有的数据,性能上存在比较大的问题;scan就是利用游标,类似于我们的分页一样

2.redis的键值对实际上使用的是类似于java中的hashtable的数据结构,key是通过哈希算法分布在一个数组中,

3.redis单线程为什么那么快:1.单线程,无线程上下文切换;2均在内存中操作;3.采用epoll,事件回调机制

4.redis持久化有三种方式:RDB、AOF、混合

RDB是根据持久化策略将redis快照成为一个二进制文件存储起来,特点是重启redis中恢复比较快,因为是二进制文件,持久化文件也比较小;

持久化策略是多少秒 发生多少次改动会触发一次快照;

RDB存在丢失数据的风险,如果在数据改动后,但是未触发持久化策略,就会丢失数据;

但是如果把RDB的快照频率设置的非常高,又会导致性能的发幅度降低,因为每次都要对所有数据进行一次快照;

AOF是将每次执行的修改指令都持久化到硬盘文件中

redis中默认的持久化策略是RDB,AOF通过设置上图中的appendonly yes来开启,AOF的持久化策略有三种,分别是appendfsync always/everysc/no:其中always是每次有新的修改指令都追加到AOF中,这样最安全,但是性能最低;everysec是每秒持久化一次,是推荐的做法,兼顾了性能和

数据安全性,最多丢失1秒的数据;no表示将数据交给操作系统来处理,不推荐这种做法。

AOF的特点是即使保证了持久化频率,但是不会导致性能下降,因为不想RDB对整个数据库进行快照,AOF只对1秒的数据进行持久化,这样即保证了性能,也保证了数据的完整性。

但是AOF文件在每次redis数据库启动时,都是读取AOF文件中的修改指令,并且一条条的顺序执行,当redis中持久化了大量的数据时,redis启动将会非常缓慢

持久化文件,我同样增加大约100W个键值对,持久化文件AOF也要比RDB要大一些,如图:

AOF重写

当我们频繁对某一个key进行操作时,例如对某一个key总是执行加锁操作,在AOF中保存的是一条条执行修改的指令,这样长期存储的指令数量会非常大,并且都是无用指令,实际上只需要执行最后一次修改即可;为了能够减少AOF文件的大小,增加redis重启加载的速度,redis默认支持AOF重写,也就是满足重写规则的情况下会将多条指令合并成最后一条有效指令,这样在加载的时候只需要执行一条指令即可,并且持久化文件也会非常小。自行测试可以再redis命令行中执行bgrewriteaof命令手动开启,redis在aof重写过程中,我们执行的修改命令不会持久化,待重写完毕后才会追加到aof持久化文件后面,持久化配置即相关说明详情见下图:

重写配置实际上是当aof增长超过100%的时候并且aof文件大小大于64M,会触发aof重写

我们自己模拟演示下aof重写:

1.我们未手动触发aof重写,对一个key进行自增10次

此时的aof文件内容是记录了对ant的十次修改操作:

2.我们清空aof持久化文件,然后使用bgrewriteaof手动开启aof重写后,再进行十次自增后的aof文件内容:

混合持久化:兼容RDB在redis重启后比较快的有点和AOF丢失数据概览比较小的特点,实际上混合持久化是aof持久化的一个变种,原理是在aof重写的时候,首先将要重写的redis内存快照以rdb中二进制的形式写到.aof文件中,并且在重写的过程中新的修改指令也存储的.aof文件中,这里实际上可以理解将aof重写那一刻之前的数据首先进行重写,减去无用的命令,其次转成rdb的二进制方法,对指令再进一步瘦身,同时保证在重写过程中新的指令会以正常aof的方式也记录到持久化文件中,最终达到兼容了aof不丢失数据并且持久化文件小,恢复快的目的;

开启混合持久化配置:

详细原理实际上在英文注释文档中写的非常详细

问题:

5.redis停止命令:./redis-cli shutdown

6.reds缓存淘汰策略:

当redis占用的内存大小超过物理内存后,会使用操作系统的虚拟内容,频繁的发生内存与磁盘进行数据交换(swap),这种情况下redis的性能会急速下降,这种情况下一般生产环境是不允许的。

一般情况下生产环境下会对redis能够使用的内容大小进行限制,并且设置redis的缓存淘汰策略,具体在redis配置文件的MEMORY MANAGEMENT中,redis的缓存淘汰策略分为8中淘汰策略,英文配置以及翻译如下图:

redis缓存淘汰策略主要分为两类:allkeys和volatile,其中allkeys是针对redis中的所有key,volatile是针对redis中带有过期时间的key;lru实际上是least recently used的意思,也就是最少使用的意思;random就是随机的意思,那么上图中的缓存淘汰策略就比较容易理解了:

volatile-xxx 策略只会针对带过期时间的 key 进行淘汰,allkeys-xxx 策略会对所有的 key 进行淘汰。如果你只是拿 Redis 做缓存,那应该使用 allkeys-xxx,客户端写缓存时不必携带过期时间。如果你还想同时使用 Redis 的持久化功能,那就使用 volatile-xxx 策略,这样可以保留没有设置过期时间的 key,它们是永久的 key 不会被 LRU 算法淘汰。

 

redis的最大内存配置如下:

7.redis架构演变:单体-》主从赋值-》哨兵-》codis-》集群cluster

8.redi cluster集群搭建步骤记录

1.创建了6台centos虚拟机

2.安装六个redis,确保安装后的每个redis都是干净的,没有持久化文件,否则在配置cluster集群时有可能会因为状态不一致情况配置失败

3.修改配置文件,将redis开放连接、后台启动、配置持久化是aof,开启混合持久化,配置最大内存以及淘汰策略,以及cluster集群配置,如下图:

4.分别启动各个redis,启动redis后查看redis进程状态可看到cluster字样

5.然后配置redis集群,此处我们一共6台redis服务器,我们配置的是一主一从,命令如下:

./redis-cli --cluster create 192.168.109.130:6379 192.168.109.131:6379 192.168.109.132:6379 192.168.109.133:6379 192.168.109.134:6379 192.168.109.135:6379 --cluster-replicas 1

其中cluster-replicas 1就表示我们创建的6个redis节点中,主从的比例是1:1,redis会一般会自动将前面3个节点作为主节点,后面3个节点作为从节点;如果我们希望创建的是两个小集群,也就是1主2从,那么设置cluster-replicas 2即可,依次类推;

有关命令帮助可以使用redis-cli help以及redis-cli --cluster help

在安装集群的过程中,要确保每一个redis都是干净的,也就是持久化文件都为空,否则配置集群启动时有可能会失败。

执行完启动命令后,结果如下:

6.我们进入通过./redis-cli -c -h xxxxx -p 6379进入redis集群的某一个节点的cli控制台,可以通过cluster nodes和cluster info查看集群相关信息;从下方图中我们可以看出设置值和获取值,会通过hash分片自动分配到不同的节点

java中使用jedis连接和使用cluster

7.我们在redis-cli中使用-c进入集群命令行:./redis-cli -c,输入cluster info和cluster nodes可以查看集群信息:

8.我们可以看到我们的每一个小集群之间的主从会自动做同步备份

8.redis集群增加一个小集群,即模拟线上压力过大增加一个主从进行分担压力

首先我们增加两台虚拟机,将redis配置称为集群模式后,启动起来,如图:

其次我们将主节点加入到集群中,通过./redis-cli --cluster help我们查看有add-node命令,默认新增的节点自动变为主节点,如图,日中参数中的existing_host是填入一个已存在的节点ip和端口,帮助找到redis集群,然后将new_host,也就是新的主节点加入到集群中

我们新加入的节点136实际上没有任何hash槽,也就是即使加入了集群,但是暂时还不能使用,我们使用上方图中的reshard命令对redis的hash槽进行重新分配:

执行 ./redis-cli --cluster reshard

How many slots do you want to move (from 1 to 16384)? 4096

(ps:需要多少个槽移动到新的节点上,自己设置,比如600个hash槽)

What is the receiving node ID? eb57a5700ee6f9ff099b3ce0d03b1a50ff247c3c

(ps:把这600个hash槽移动到哪个节点上去,需要指定节点id)

Please enter all the source node IDs.

  Type 'all' to use all the nodes as source nodes for the hash slots.

  Type 'done' once you entered all the source nodes IDs.

Source node 1:all

(ps:输入all为从所有主节点(8001,8002,8003)中分别抽取相应的槽数指定到新节点中,抽取的总槽数为600个)

 ... ...

Do you want to proceed with the proposed reshard plan (yes/no)? yes

(ps:输入yes确认开始执行分片任务)

... ...

 

分片完成后,我们可以看到新的136主节点已经有了指定数量的hash槽:

我们接下来将新的137从节点挂在136主节点下面,通过./redis-cli --cluster help命令的add-node我们可以看到该命令后方有参数,可以直接挂从节点:

从节点挂成功后,我们看集群状态可以看到目前小的集群一共有四个,四主四从:

我们看,其实整体key的分布还是比较均匀的

9.redis cluster集群原理分析

redis cluster会将所有的数据划分为16384个槽位,每一个小集群都会负责其中一部分槽位,每一个新增和查询时,redis会使用crc16算法对key进行hash得到一个整数值,然后对16384进行取模,最终确定这个key在哪个集群上面。

redis cluster使用cluster-node-timeout配置,认为当某个节点失联时间超过配置时间认为该节点出现故障,解决网络抖动问题。

如果同一个小集群出现两个master,那么会出现脑裂现象??

redis cluster最多可以扩容16384个小集群,即一个槽一个小集群,但是官网推荐在1000以内,否则性能会下降

redis集群最起码也要是3个节点,用于选举;如果是2个节点,那么当一个master挂了,他的slave节点不能被选举为master节点成功,因为投票数量达不到半数以上

当slave发现自己的master变为FAIL状态时,便尝试进行Failover,以期成为新的master。由于挂掉的master可能会有多个slave,从而存在多个slave竞争成为master节点的过程, 其过程如下:

1.slave发现自己的master变为FAIL

2.将自己记录的集群currentEpoch加1,并广播FAILOVER_AUTH_REQUEST 信息

3.其他节点收到该信息,只有master响应,判断请求者的合法性,并发送FAILOVER_AUTH_ACK,对每一个epoch只发送一次ack

4.尝试failover的slave收集FAILOVER_AUTH_ACK

5.超过半数后变成新Master

6.广播Pong通知其他集群节点。

 

从节点并不是在主节点一进入 FAIL 状态就马上尝试发起选举,而是有一定延迟,一定的延迟确保我们等待FAIL状态在集群中传播,slave如果立即尝试选举,其它masters或许尚未意识到FAIL状态,可能会拒绝投票

•延迟计算公式:

 DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms

•SLAVE_RANK表示此slave已经从master复制数据的总量的rank。Rank越小代表已复制的数据越新。这种方式下,持有最新数据的slave将会首先发起选举(理论上)。

 

10.jedis源码分析

jedis使用的BI/O进行与redis进行交互,letture使用Netty对redis进行交互

redis集群中每一个redis的database只有一个库:0,单机版我们一般正常有16个库

监控系统:FaIcon和Zabbix

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章