目录

 

fork操作:

salve复制:

数据同步:

读写分离:

阻塞:

理解内存

内存回收策略

哨兵

集群

故障发现


fork操作:

当redis进行RDB和AOF重写时,会fork创建子进程

fork创建不需要父进程物理内存空间,但会赋值父进程的内存空间页表

fork耗时问题:

info:last_fork_usec正常耗时20ms/GB

优先使用物理机

控制每个Redis实例的内存

合理控制Linux内存,避免fork失败

降低fork频率(AOF触发时机)

监控:可以编写shell脚本监控log定位问题

Linux内核:THP页分配 star iostat iotop

salve复制:

slaveof ip port建立连接

slaveof no one断开连接

slave-read-only=yes线上不要修改只读模式,防止出现数据不一致

repl-diable-tcp-nodelay设置传输延迟

数据同步:

psync命令:

psync {runId} {offset}

主从各自复制偏移量:

  主节点处理完写入命令后,把命令长度做累加记录,统计在info replication master_repl_offset

  从节点每秒钟上报复制偏移量给主节点info replication slave_repl_offset

主从复制挤压缓冲区:

  在主节点上的一个固定大小的队列(默认1MB)

主节点运行id:

  因为每次重启运行ID会发生变化,根据ip和port的话会有问题,比如重启替换了RDB或AOF,数据的偏移量是不对的,应该全量复制

  如何在不改变运行ID的情况下重启?使用debug reload(会阻塞主线程)

全量复制:

一般用于初次复制,复制时候会把主节点在这期间的数据写命令保存到复制缓冲区(client-output-buffer-limit slave256MB64MB60)

从节点加载RDB的时候,依然响应读命令(slave-server-stale-data开启),无法容忍不一致可关闭

部分复制:用于因网络闪断等原因造成的数据丢失

心跳:

主节点每隔10s对从ping

从节点每隔1s发送replconf ack {offset},给主节点同步偏移量

读写分离:

使用从节点响应请求,可能存在下列问题:

复制数据延迟

监听主从节点的复制偏移量,当延迟较大时发送报警

可以采用zookeeper回调通知,切换客户端路由

读到过期数据

删除策略:惰性删除、定时删除

3.2版本已经解决

从节点故障

和数据延迟一样zookeeper

避免复制风暴:

一主多从,采用树状结构

单机多实例,主节点分散部署

阻塞:

发现阻塞:

客户端有异常JedisConnectionException(要打印ip port),借助日志系统报警

监控系统,指标:命令耗时、慢查询、持久化阻塞、链接拒绝、CPU/内存/网络/磁盘过载

内在原因:

api或数据结构使用不合理

slowlog get {n}:超时默认10ms,队列长度默认128

bigkeys发现大对象

CPU饱和

stat发现redis使用情况

info commandstats发现命令不合理开销时间

持久化阻塞

fork阻塞:info stats获取latest_fork_usec指标获取最近一次fork耗时

AOF刷盘:info persistence统计中aof_delayed_fsync

HugePage写操作:对于开启Transparent HugePages的会引起内存页单位放大

外在原因:

CPU竞争

top、star查看CPU消耗时间点和进程

绑定CPU,降低CPU切换的开销:开启了RDB和AOF以及slave不要这样做

内存交换

查看进程id:redis-cli -p 6379 info server | grep process_id

根据进程号查看内存交换信息:cat /proc/4476/smaps | grep Swap (0或4k正常)

降低系统swap优先级:echo 10>/proc/sys/vm/swappiness

网络问题

网络闪断:sar -n DEV查看流量是否正常

redis拒绝链接:info stats的rejected_connections设置tcp-keepalive和timeout让redis主动关闭

连接溢出:进程限制(ulimit -n)设置成65535防止too many open files

backlog队列溢出:netstats -s | grep overflowed查看连接拒绝的统计

网络延迟:使用–latency --latency-history

网卡软中断:top1中的si指标

理解内存

内存统计:mem_fragmentation_ratio >1:碎片 <1:内存交换

对象内存:数据结构

缓冲内存:客户端缓冲区、复制缓冲区、AOF缓冲区

内存碎片:jemalloc分配内存(频繁更新、大量过期键)

解决:数据对齐、安全重启

子进程内存消耗:THP问题(关闭它),sysctl vm.overcommit_memory=1允许分配所有内存

设置内存上限:

maxmemory实际的内存因为内存碎片的存在,要更大,超过的部分根据LRU淘汰

动态调整内存上限:

内存回收策略

删除过期键:

惰性删除:读取时返回空(内存泄漏,比如长久不访问就不会删)

定时任务删除:默认每秒运行10次(根据过期比例、使用快慢两种速率模式回收键)

内存溢出控制策略:

随机删,不删拒绝写、LRU删、过期键删

一般环境下才可以使用调小maxmemory,达到快速回收目的

缩减key value的长度;采用序列化工具

共享对象池:开启LRU相关淘汰策略,共享技术被禁止使用

哨兵

这部分雪球内部旧的方案,相比于gossip的cluster集群,不在解释

集群

哈希分区:

节点取余

一致性哈希:

加减节点会造成哈希环中部分数据无法命中

少量节点时,节点变化影响哈希环中数据映射

普通的一致性需要一半才能负载均衡

虚拟槽分配CRC16校验

redis数据分区:

解耦数据和槽之间的关系

支持点、槽、键之间映射

只有16384个槽全部分配完毕之后,集群才创建成功

goosip协议Gossip协议

选择发送消息节点的数量:cluster_node_timeout

消息数据量:并不是越大越好

集群伸缩:

有坑啊,注意:使用redis-trib.rb比较好,如果直接meet,不会检查新节点的数据造成紊乱

迁移后使用redsi-trib.rb rebalance ip:port检查节点槽之间的均衡性

MOVE重定向是在client端完成,client缓存了一个node和slot的对应关系

ACK重定向

故障发现

主观下线:某个节点认为另外一个节点不可用

客观下线:集群内多个节点认为该节点下线

恢复:

短线时间>cluster-node-time*cluster-slave-validity-factor

根据从节点的复制偏移量offset设置优先级

更新configEpoch配置纪元

故障转移时间:

偏移量最大的从节点会在1000ms完成转移

故障转移时间和cluster-node-timeout息息相关(默认15s)

07-07 18:36