优化慢日志
127.0.0.1:6379> slowlog get (n 获取条数,默认为10条)
监控慢日志,修改配置文件redis.conf:
slowlog-log-slower-than 10000 #单位微秒
slowlog-max-len 选项指定服务器最多保存多少条慢查询日志
发现bigkey
命令
redis-cli --bigkeys
采用scan 方式,分析bigkey以及每种字段类型平均使用内存情况
查看redis使用情况 redis info 命令相关
详细的可以看 http://redisdoc.com/server/info.html
查看当前使用情况:
redis-cli info [memory | replication|...]
一.查看内存
redis-cli info memory
used_memory_human:192.54M #redis使用的内存,包括swap分区
used_memory_rss_human:256.61M #物理内存总量(俗称常驻集大小)一般used_memory_rss的值只应当比used_memory的值稍微高一点,如果差距很大,说明有内存碎片
used_memory_peak_human:227.46M #r内存消耗峰值 ??
total_system_memory_human:31.36G #系统内存
used_memory_lua_human:37.00K #lua脚本引擎使用的内存总量
maxmemory_human:0B #Redis能够使用的最大内存上限(0表示没有限制),以字节为单位
maxmemory_policy:noeviction #redis内存回收策略[noeviction、allkeys-lru、volatile-lru、allkeys-random、volatile-random、volatile-ttl]
mem_fragmentation_ratio:1.33 #内存碎片的比率(过大的话需要重新导入)
主要观察两个指标:
1. used_memory_rss 和 used_memory 或 mem_fragmentation_ratio
used_memory_rss > used_memory 说明有内存碎片,过大的话需要重新导入
used_memory_rss < used_memory 说明内存不够用,要加机器内存或者修改最大内存的值了
内存碎片产生原因:
额外碎片的产生是由于Redis释放了内存块,但内存分配器并没有返回内存给操作系统,这个内存分配器是在编译时指定的,可以是libc、jemalloc或者tcmalloc。会导致,实际占用内寸高的问题
解决办法:重启Redis服务器~?
二.查看客户端连接情况
redis-cli info clients
# Clients
connected_clients:313 #客户端连接的数量(来自从机的连接除外)
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0 #由于阻塞调用(BLPOP、BRPOP、BRPOPLPUSH)而等待的客户端的数量。
三、查看Redis服务器状态
redis-cli info Stats
total_connections_received:56 #启动来Redis服务器接受的连接总数
total_commands_processed:52393 #处理的命令总数
instantaneous_ops_per_sec:6 #每秒钟处理的命令数量
total_net_input_bytes:1862414 #通过网络接收的数据总量,以字节为单位。
total_net_output_bytes:750529 #通过网络发送的数据总量,以字节为单位。
instantaneous_input_kbps:0.25 #每秒接受数据速率
instantaneous_output_kbps:0.07 #每秒发送数据速率
rejected_connections:0 #由于maxclients限制而拒绝的连接数量
#主从相关
sync_full:0 #主机和从机进行完全同步的次数
sync_partial_ok:0
sync_partial_err:0
expired_keys:1 #过期键总数
evicted_keys:0 #由于maxmemory限制,而被回收内存的键的总数。
keyspace_hits:35919 #在主字典中成功查找到键的次数。
keyspace_misses:567 #在主字典中未能成功查找到键的次数。???
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:894
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0
四、查看命令使用情况
redis-cli info commandstats
命令 ----调用次数----命令消耗的CPU时间总量-----每次执行命令消耗CPU时间的平均值(微秒)
cmdstat_get:calls=1042987138,usec=3100245183,usec_per_call=2.97
cmdstat_set:calls=8405476,usec=51001447,usec_per_call=6.07
cmdstat_setex:calls=27187256,usec=339466461,usec_per_call=12.49
cmdstat_del:calls=1953523,usec=10125078,usec_per_call=5.18
cmdstat_exists:calls=4083927,usec=12597033,usec_per_call=3.08
cmdstat_incr:calls=26561,usec=181897,usec_per_call=6.85
...
五、查看redis 各个库使用情况 :redis-cli info keyspace
数据库编号--------键数量--------过期key数量--------键平均生寸时间
db0:keys=10438,expires=0,avg_ttl=0
db1:keys=23,expires=3,avg_ttl=202262388
db5:keys=4,expires=0,avg_ttl=0
db6:keys=1,expires=1,avg_ttl=814949
六、查看实时redis使用情况
redis-cli monitor (这个命令线上禁止使用!很消耗性能)
redis AOF VS RDB
RDB(Redis DataBase)和AOF(Append Only File)
简单的说:RDB 是某个时间节点redis数据的快照,AOF是类似mysql binglog日志,将redis执行的指令保存下来。两种都是为redis数据备份方式。两者不冲突,可以同时开启~也可以只保留一个(aof 默认没有开启)
RDB优点
- RDB 在重启保存了大数据集的实例时比 AOF 要快(因为RDB是一个快照,AOF是很多指令合计)
- RDB 持久化时只需要父进程fock(但是fock的时候也会阻塞主进程)一个子进程,不影响父进程性能
- 可以复制RDB文件进行redis数据替换
RDB缺点
- RDB设置每隔多长时间多少个键值发生改变才进行快照替换(数据可能会丢失一部分)
- RDB是全量复制,如果数据集比较大时,fork的过程非常耗时也很吃机器性能。
AOF优点
- AOF最多只会丢失一秒数据,数据完整性高
- AOF是一个追加文件,在断电时也没有损坏问题,即使文件末尾写到一半,使用redis-check-aof 也可以很快修复
- AOF里面是一个一个的操作指令,很容易理解和解析,如果执行了误操作,可以打开aof日志文件删除对应的那行,然后重启恢复数据
AOF缺点
- 相同数据集的数据aof文件要远大于rdb文件,恢复速度慢于rdb(即使有AOF重写机制)
- aof运行效率低于rdb
AOF和RDB如何开启以及相关配置参数
AOF
- aof 3种策略 always,every second,no (由系统决定什么时候追加)
- 原生aof 和aof 重写(bgrewriteaof 类似生成rdb 文件)(将过期的,多次设置的key 压缩成小文件)节约硬盘,加快恢复速度
AOF 配置参数
appendonly yes(默认关着的)
appedfilename
appendfsync everysec
dir
no-appndfsyc-on-rewrite yes(aof 每秒备份,和重写之间可能会有冲突,并且耗性能,一般选择yes 可能会丢失部分数据)
aof 重写配置参数
aoto-aof-rewrite-min-size 文件重写需要尺寸
aoto-aof-rewrite-percentage 文件增长率
RDB(redis 默认持久化方式)
RDB配置文件
rdbcompression yes #是否启用压缩,优点减少磁盘存储空间,消耗CPU资源
dbfilename dump.rdb # rdb文件名
dir ./ # rdb文件存储路径
save 900 1 # 15分钟内至少有一个键被更改
save 300 10 # 5分钟内至少有10个键被更改
save 60 10000 # 1分钟内至少有10000个键被更改
手动执行备份
- AOF 可以使用BGREWRITEAOF命令来重写AOF文件
- RDB 可以使用SAVE和BGSAVE 来进行备份
AOF 和 RDB 如何选择
- 如果允许数据丢失一部分而且数据可以从数据库补齐,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则
- AOF ~~~明天再研究、、AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上。默认超过原大小100%大小时重写可以改到适当的数值。
- 采用 主从结构,挂了也可以实现高可用……
进行数据备份子进程开销
- CPU
- 不做CPU绑定
- 不和CPU密集型应用一起部署。单机多部署,防止进行同时aof和rdb重写
内存 - fork 内存开销,理论上,fork内存消耗等于父进程,但是linux 中有显示复制(copy-on-write)父子进程可以共享共同的物理内存页,当父进程有写请求时,会创建一个副本(这个时候才会消耗内存)子进程可以共享父进程物理内存快照。-----当重写的时候,父进程有大量写入时,子进程内存开销比较大。
- linux 2.6.38内核中增加THP特性,支持大的内存页分配。为了增加frok速度。
echo never > /sys/kernel/mm/transparent_hugepage/enable
- 硬盘消耗
- 不要和高负载服务部署在一起:存储服务,消息队列
- no-appendfsync-on-rewirte =yes (aof重写期间,不进行aof追加)
- 使用SSD
- 单机多部署使用分盘 cgroup限制硬盘资源的分配
线上禁止使用的命令
keys,flushall,flushdb,slow lua script,mutil/exec,operate big value(collection)
Tip
- 如果配置了主从没有使用redis-sentinel,主库挂掉重启时,不能直接重启主库,否则会覆盖掉从库的aof文件
不重启修改配置信息
redis-cli config set appendonly yes
有些配置必须重启才可~ 比如bind