redis key命名规范

1.建议全部大写

2.key不能太长也不能太短,键名越长越占资源,太短可读性太差

3.key 单词与单词之间以  : 分开

4.redis使用的时候注意命名空间,一个项目一个命名空间,项目内业务不同命名空间也不同。

 

user

id

userName

age

1

zhangsan

18

2

lisi

16

 

 

 

 

一般情况下:

  1) 第一段放置项目名或缩写 如 project

  1) 第二段把表名转换为key前缀 如, user:

  2) 第三段放置用于区分区key的字段,对应mysql中的主键的列名,如userid

  3) 第四段放置主键值,如18,16

结合起来  PRO:USER:UID:18

 

常见的设置登录token

key:  PRO:USER:LOGINNAME:373166324   

value:12kd-dsj5ce-d4445-h4sd472

 

redis的过期策略

redis过期策略有两种,一种是主动式过期,另一种是被动式过期,redis采用两者相结合的方式来处理,因为单纯采用主动式过期,会影响redis的性能,单纯采用被动式过期,可能会导致大量内存得不到释放。

主动式过期(定期删除):

    redis会将所有设置了过期时间的key放到一个独立的字典中,以后会定时扫描这个字典,将过期的key删除。redis默认每秒进行10次过期扫描,扫描不会扫描所有的key,而是采用一种贪心的策略来进行:

1. 从过期字典中随机选择20个key。

2. 将20个key中过期的key删除。

3. 如果过期的key的比例超过1/4,redis认为过期的key相对较多,会再次从步骤1依次执行。

同时为了保证扫描不会出现过度循环影响性能,redis会限制每次扫描的时间上限为25ms。

 

被动式过期(惰性删除):

    redis定时扫描任务可能不会将过期的key完全删除,此时redis会用一种懒惰策略来被动式的更新过期的key,即当这个key被实际访问时,redis会检查这个key的过期状态,如果过期,那么将这个key删除

定时删除(基本不用):

    在设置key的过期时间的同时,为该key创建一个定时器,让定时器在key的过期时间来临时,对key进行删除

缺点 : 若有很多个key同时到期,将会占用cpu大量的时间来删除key,不能让cpu做要紧的事,同时给key设置定时器也需要消耗一定的时间

 

redis 内存淘汰机制:

noeviction: 当内存不足以容纳新写入数据时,新写入操作会报错。
allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(常用)。
allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key。
volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 key(这个不太适)。
volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 key。
volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除。

大key问题

redis 重命名命令 生效 redis命名空间_redis

出现大key的两种情况:

  1. 字符串: 单个的key存储的value值过大
  2. list hash set zset存储过多的元素

大key的风险:

因为redis是单线程的,对大key的读,写,删除可能会占用很长的事件,造成阻塞

大key的判别: 

redis在计算大key的时候不是以key的占用内存大小来计算的,string是使用STRLEN方法来计算,list是llen来计算。

解决大key问题:

1 . 字符串: 单个的key存储的value值过大

  1. 可以将一个大key的value值拆分,存储到多个key中
  2. 也可以将value的值存储到hash中, field代表一个具体的属性,使用hget,hmget获取值,使用hset,hmset更新值

2. list hash set zset中存储过多的元素

将这些元素进行分拆

以hash为例,原先的正常存取流程是  hget(hashKey, field) ; hset(hashKey, field, value)

现在,固定一个桶的数量,比如 10000, 每次存取的时候,先在本地计算field的hash值,模除 10000, 确定了该field落在哪个key上

newHashKey  =  hashKey + (*hash*(field) % 10000);   
hset (newHashKey, field, value) ;  
hget(newHashKey, field)

删除大key :

hash key : 通过hscan命令 , 每次获取500字段, 再用hdel命令删除

set key : 使用sscan命令, 每次扫描500字段, 再用srem命令每次删除一个元素

list key : 通过使用ltrim命令每次删除少量元素

sorted set key : 使用sortedset自带的zremrangebyrank命令删除 top100个元素

key的扫描

scan命令扫描返回两个参数:

  1. 下次扫面游标所在的位置
  2. 本次扫描出来的全部结果