zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

redis运维维护

Redis运维 维护
2023-09-11 14:21:09 时间

【运维】

【0】操作系统优化

#【1】调整 vm.overcommit_memory
#vi /etc/sysctl.conf
echo "vm.overcommit_memory=1" >> /etc/sysctl.conf

#改参数关注的是内存分配策略
#0,标识内核将检查是否有足够的可用内存供应用进程使用;如果有则申请允许,否则内存申请失败,并返回错误给应用进程。
#1,标识内核允许分配所有的物理内存,而不管当前的内存状态如何。
#2,标识内核允许分配超过所有物理内存和交换空间(swap)的内存

#【2】调整 Transparent Huge Pages(THP)
#解决:redis 做 rdb 时会有部分请求超时的情况

echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo "never > /sys/kernel/mm/transparent_hugepage/enabled" >> /etc/rc.local

#【3】TCP backlog设置(详情见后续redis配置参数)
echo 2048 > /proc/sys/net/core/somaxconn
echo "net.core.somaxconn=2048" >> /etc/sysctl.conf
#动态加载
sysctl -p

#此参数确定了TCP连接中已完成队列(完成三次握手之后)的长度
#此值必须不大于linux系统定义的 /proc/sys/net/core/somaxconn的值,默认511
#而 linux 默认参数值是128,当系统并发量大并且客户端缓慢时,可以将这2个参数一起参考设置。

 

【1】持久化

(1)主库开启持久化或主库不设置开启自启

  当主库没有开启持久化时,注意不要设置开机自启。

  因为主库如果宕机重启后数据为空,这个时候如果重启了,那么主库数据为空,从库会重新同步新的空白数据 导致从库被清空。

(2)stop-writes-on-bgsave-error 参数设置为 no

  当RDB持久化出现错误后,是否依然进行继续进行工作。

    yes:不能进行工作

    no:可以继续进行工作

  可以通过info中的rdb_last_bgsave_status了解RDB持久化是否有错误,如果设置成了YES则RDP文件如果持久化失败则整个实例宕机无法写入

(3)AOF参数:no-appendfsync-on-rewrite 参数设置为 no/yes

  当执行bgrewriteaof 对aof文件重写时,不做预设的自动追加同步操作到aof文件上去。但默认会按30秒一次批量同步操作到aof文件中去。

  该操作是为了避免大量磁盘操作导致系统卡顿

    yes:当做 rewrite 操作时,不使用预设频率对新操作持久化同步到  aof 文件中去,而是用默认的30S同步一次;      该选项可能在极端情况下导致丢失30秒数据

    no:当做 rewrite 操作时,继续维持原有的预设同步频率同步redis操作到 aof 文件中去。

  建议HDD用 yes,SDD 用 no 。注意如果选 yes 该选项可能在极端情况下导致丢失30秒数据

 【2】复制

(1)断开复制、重新连接其他主库(会清空之前数据)

  切换主节点之后,从节点会清空之前的所有数据,线上操作的时候需要注意

(2)repl-backlog-size 5mb

复制积压缓冲区大小,为了避免网络闪断而缓冲区大小不够导致主从无法进行psync部分同步而重新进行全量复制同步,根据数据量来判断

复制积压缓冲区的最小大小可以根据公式 second*write_size_per_second 来估算:

  1. 其中second为从服务器断线后重新连接上主服务器所需的平均时间(以秒计算);
  2. 而 write_size_per_second 则是主服务器平均每秒产生的写命令数据量(协议格式的写命令的长度总和);

例如,如果主服务器平均每秒产生1 MB的写数据,而从服务器断线之后平均要3秒才能重新连接上主服务器,那么复制积压缓冲区的大小就不能低于3MB。

 

【常用命令】

【2.1】基本数据库信息命令

redis 127.0.0.1:6380> dbsize  // 当前数据库的key的数量

redis 127.0.0.1:6380> select 2 //切换数据库

BGREWRITEAOF  //后台进程重写AOF

BGSAVE       //后台保存rdb快照

SAVE         //保存rdb快照,会阻塞,建议使用BGSAVE

LASTSAVE     //上次保存时间Slaveof master-Host port  //把当前实例设为master的slave

Flushall  //清空所有库所有键

Flushdb  //清空当前库所有键

Showdown [save/nosave] //关闭,然后持久化保存/不持久化保存

//注: 如果不小心运行了flushall, 立即 shutdown nosave ,关闭服务器
//然后 手工编辑aof文件, 去掉文件中的 "flushall" 相关行, 然后开启服务器,就可以导入回原来数据.
//如果,flushall之后,系统恰好bgrewriteaof了,那么aof就清空了,数据丢失

config get *    //获取所有配置参数值

config set item value  //设置某个 item的值 为 value

config rewrite  //把做了 config set 修改的参数配置值 写入到配置文件中去。


【2.2】监控相关信息

Info [Replication/CPU/Memory..]

查看redis服务器的信息

 

Config get 配置项 

Config set 配置项 值 (特殊的选项,不允许用此命令设置,如slave-of, 需要用单独的slaveof命令来设置)

 

Redis运维时需要注意的参数

1: 内存 info Memory

used_memory:5297393328           //redis 数据结构的占用空间

used_memory_rss:6213394432    // 操作系统层面实占空间

mem_fragmentation_ratio:1.89     // used_memory_rss/used_memory  1.N 为佳

  // 如果该值 > 1时,则说明 used_memory_rss - used_memory_rss 多出的内存部分并没用于存储数据,而是被内存随便所消耗,如果很大则碎片严重,建议重新导出导入

  // 如果该值 < 1时,则说明 redis 使用的内存,比操作系统分配给它的还要多,那么多半是使用了 swap 交换内存。这种情况要格外注意

2: 主从复制 info replication

role:slave

master_host:192.168.1.128

master_port:6379

master_link_status:up

 

3:持久化 info Persistence

rdb_changes_since_last_save:0

rdb_last_save_time:1375224063

 

4: fork耗时 info Stats

latest_fork_usec:936  上次导出rdb快照,持久化花费微秒

注意: 如果某实例有10G内容,导出需要2分钟,

每分钟写入10000次,导致不断的rdb导出,磁盘始处于高IO状态.

 

 

5: 慢日志

config get/set slowlog-log-slower-than  //配置慢查询阀值

CONFIG get/SET slowlog-max-len  //配置慢日志最大记录数

slowlog get N //获取慢日志

slowlog len  //获取慢日志记录条数

Slowlog 显示慢查询

注:多慢才叫慢?

答: 由slowlog-log-slower-than 10000 ,来指定,(单位是微秒)

 

服务器储存多少条慢查询的记录?

答: 由 slowlog-max-len 128 ,来做限制

 

【2.3】redis-cli 查看信息

1: --stat 输出当前 redis 服务节点状态

命令:redis-cli -h host -p port --stat

输出:

连续输出,默认interval 1s

键数 | 内存 | 客户端数 | 阻塞数 | 累积请求(增加请求) | 连接数

2: --bigkeys 扫描大key

命令:redis-cli -h host -p port --bigkeys

输出:

执行 scan 操作,单次100。不影响服务器实时性能。 

3: --scan 查看key

结合linux命令 more 查看

命令:redis-cli -h host -p port --scan | more

匹配:--pattern '*hello*'

命令:redis-cli -h 10.10.52.100 -p 10119 --scan --pattern '*hello*'

输出:

统计:| wc -l

命令:redis-cli -h 10.10.52.100 -p 10119 --scan --pattern '*hello*' | wc -l

4: --latency 延迟统计

命令:redis-cli -h host -p port --latency

输出:

 

历史延迟统计:间隔15s输出统计结果

命令:redis-cli -h host -p port --latency-history

输出:

更直观的命令输出:--latency-dist,

命令:redis-cli -h host -p port --latency-dist

输出:

5: --rdb 备份镜像

命令:redis-cli -h host -p port --rdb

输出:

6: --lru-test 测试Redis的LRU实现的质量

模拟使用80-20%幂律分布来执行对GET和SET操作的模拟。

命令:redis-cli -h host -p port --lru-test 测试键数

输出:

7: -r 连续重复执行

命令:redis-cli -h host -p port -r 10 incr AB

输出:

 

 

【开发技巧】

 

使用 INCR,而不是 x=x+1

  1. 客户端A读取计数为10。
  2. 客户端B读取的计数为10。
  3. 客户A增加11,并将计数设置为11。
  4. 客户端B增加11,并将计数设置为11。

我们希望该值为12,但实际上为11!这是因为以这种方式增加值不是原子操作。在Redis中调用 INCR命令可以防止这种情况的发生,因为它是原子操作
由单个命令实现的所有Redis操作都是原子的,包括对更复杂的数据结构进行操作的操作。因此,当您使用修改某些值的Redis命令时,无需考虑并发访问。

 

使用setnx,而不是 set

  1. 原子性,可以用于实现分布式事务
  2. 更安全,不存在则创建

 

使用 mget/mset,而不是 get/set

同理,其他数据类型也一样。
1000次 get 和 1次 mget 对比表

操作时间
1000次get 1000*1+1000*0.1=1100毫秒=1.1秒
1次mget(组装了100个键值对) 1*1+1000*0.1=101毫秒=0.101秒

 

使用 scan/hscan 等系列,而不是 keys/getall/smembers/zrange

优势:

  1. scan 是渐进式遍历,不会一下子遍历所有key,它的时间复杂度是O(1)
  2. scan 因为是渐进式遍历不会阻塞,不会像keys那样在有大量key时比较容易造成阻塞

问题:

  1. scan 渐进式遍历可以有效解决keys 命令可能产生的阻塞问题,但是 scan也有自己的问题。
  2. 在scan的过程中如果有key有增删改变化,那么遍历的效果可能不尽人意
    • 新增的键可能没有遍历到
    • 遍历出现了重复的键

也就是说,scan 可能无法遍历检索出所有的key,这是我们需要考虑的。

【需要注意的点】

  1. persist 命令会删除任意类型键的过期时间
  2. set系列 命令也会删除字符串等类型的过期时间

【参考文件】

阿里云redis开发规范:https://developer.aliyun.com/article/531067