【Redis】大键查看方法汇总

本文介绍了Redis中大键可能导致内存超限的问题及如何检测大键。提供了三种方法:1) 使用redis自带的`--bigkeys`命令,但只适用于特定数据类型的最大键;2) 使用Python脚本遍历并检查key的大小,适用于主从和集群版本,阈值默认为10240;3) 解析rdb文件并通过rdbtools转换为csv分析。优化原则包括减少string长度和集合成员数。
摘要由CSDN通过智能技术生成

redis 大键查看方法汇总


前言

在操作Redis时,提示“内存不足org.redisson.client.RedisOutOfMemoryException: command not allowed when used memory > ‘maxmemory’.”。说明当前redis的某个节点内存使用超限!!
本文重点介绍 如何查看大键的分布。

一、key是如何分布的

1、集群版Redis是分片(db节点)部署的,每个db节点会分配一定数量的哈希槽(集群版redis内置16384个哈希槽)。存储key的时候,首先根据CRC16算法得出一个值,并对16384取模,取模结果即是该key需要落的slot位置,根据slot所属db节点来存储key;
2、每个db节点都有最大内存限制(maxmemory),当某个db的节点内存使用达到上限,会执行相应的内存逐出策略。
内存逐出策略

二、查看big key

1.使用redis自带–bigkeys命令

redis-cli -h xxxx -p xxxx -a "passwd" -–bigkeys
说明:
1)该方法只能查看每种数据类型最大的key;
2)生产环境需要用户侧执行,建议业务低峰期操作

在这里插入图片描述

2.使用python脚本查看

#python find_bigkey.py hostxxx 6379 $password

import sys
import redis

def check_big_key(r, k):
  bigKey = False
  length = 0 
  try:
    type = r.type(k)
    if type == "string":
      length = r.strlen(k)
    elif type == "hash":
      length = r.hlen(k)
    elif type == "list":
      length = r.llen(k)
    elif type == "set":
      length = r.scard(k)
    elif type == "zset":
      length = r.zcard(k)
  except:
    return
  if length > 10240:
    bigKey = True
  if bigKey :
    print db,k,type,length

def find_big_key_normal(db_host, db_port, db_password, db_num):
  r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, db=db_num)
  for k in r.scan_iter(count=1000):
    check_big_key(r, k)

def find_big_key_sharding(db_host, db_port, db_password, db_num, nodecount):
  r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, db=db_num)
  cursor = 0
  for node in range(0, nodecount) :
    while True:
      iscan = r.execute_command("iscan",str(node), str(cursor), "count", "1000")
      for k in iscan[1]:
        check_big_key(r, k)
      cursor = iscan[0]
      print cursor, db, node, len(iscan[1])
      if cursor == "0":
        break;
  
if __name__ == '__main__':
  if len(sys.argv) != 4:
     print 'Usage: python ', sys.argv[0], ' host port password '
     exit(1)
  db_host = sys.argv[1]
  db_port = sys.argv[2]
  db_password = sys.argv[3]
  r = redis.StrictRedis(host=db_host, port=int(db_port), password=db_password)
  nodecount = r.info()['nodecount']
  keyspace_info = r.info("keyspace")
  for db in keyspace_info:
    print 'check ', db, ' ', keyspace_info[db]
    if nodecount > 1:
      find_big_key_sharding(db_host, db_port, db_password, db.replace("db",""), nodecount)
    else:
      find_big_key_normal(db_host, db_port, db_password, db.replace("db", ""))

该方法支持阿里云Redis的主从版本和集群版本的大key查找,默认大key的阈值为10240,也就是对于string类型的value大于10240的认为是大key,对于list的话如果list长度大于10240认为是大key,对于hash的话如果field的数目大于10240认为是大key。另外默认该脚本每次搜索1000个key,对业务的影响比较低,不过最好在业务低峰期进行操作,避免scan命令对业务的影响。
参考:https://developer.aliyun.com/article/117042

3.解析redis的rdb文件

该方法是使用rdbtools工具将redis的rdb文件解析成csv文件,再直接分析csv或导入mysql后分析。

# rdb -c memory /wjqdata/redis/rdb/dump.rdb --bytes 128 -f /wjqdata/redis/rdb/test.csv
# cat test.csv | awk -F',' '{print $4,$2,$3,$1}' | sort -nr | head -50   //对键值大小进行排序

参考:https://www.cnblogs.com/cheyunhua/p/10598181.html

总结

优化big key的原则就是string减少字符串长度,list、hash、set、zset等减少成员数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值