Redis Key 的命名策略

  Redis 是 K-V 形式的缓存数据库,每一个需要缓存的 Object 都需要唯一的 Key 来标识。但是,我们日常在做开发的时候,经常会出现一个公司或者部门之间共用一个 Redis 集群的情况。所以,这就有可能会造成 Key 冲突,引发数据被覆盖的问题(即使是同一个部门,也可能存在不同的研发人员使用了同名的 Key)。

  根据业务名称命名 - 不建议

  一个项目中,相似的业务是很常见的,所以,如果不同的研发人员使用了同名的 Key,就会导致系统的 bug。同时,如果不同的项目组在共同使用一个 Redis 集群,也会发生这样的问题。例如:

  127.0.0.1:6379 set name qinyi

  OK

  # 同一个项目中的不同业务使用了同名的 key (不同的研发人员共同开发造成)

  127.0.0.1:6379 lpush name qinyi imooc

  (error) WRONGTYPE Operation against a key holding the wrong kind of value

  127.0.0.1:6379

  在业务名称之前加上项目的名称 - 不建议

  这样做可以大概率的避免不同的项目引起的 Key 冲突问题,但是,仍然不能避免同一个项目中的不同业务。例如:

  # a、b 两个项目在使用 Redis 时,各自以项目的名称为 Key 的前缀

  127.0.0.1:6379 set a-name qinyi

  OK

  127.0.0.1:6379 set b-name imooc

  OK

  # 仍不能避免同一个项目中的不同业务使用了同名的 key

  127.0.0.1:6379 lpush a-name qinyi imooc

  (error) WRONGTYPE Operation against a key holding the wrong kind of value

  127.0.0.1:6379

  Key = 项目名称-业务名称-时间戳 - 建议

  这种命名 Key 的方式是比较好的,相比于上一种方式,多增加了一个时间戳标识。这里的含义就是与不同的开发人员定义相同时间戳的概率很低很低。具体时间戳的精度可以根据业务的实际情况选择,比如:天、小时等等。例如:

  # Key 中添加天级的时间戳来避免 Key 冲突的问题

  127.0.0.1:6379 set a-name-20190314 qinyi

  OK

  127.0.0.1:6379 lpush a-name-20190315 qinyi imooc

  (integer) 2

  127.0.0.1:6379

  过期时间的设定

  在使用 Redis 时,绝大多数情况都需要给 Key 设定过期时间,这个是非常有必要的。原因如下:

  作为缓存,加快程序的执行速度。但是缓存的 Object 很可能是会经常变化的,不要长期驻留在 Redis 中

  当 Redis 的内存使用超过一个阈值(可以自定义)时,会触发 Redis 的缓存淘汰策略,此时的 LRU 过程是非常慢的。极大的影响 Redis 的性能

  所以,在保存 KV 时,最好是设定过期时间。例如:

  127.0.0.1:6379 set name qinyi

  OK

  127.0.0.1:6379 expire name 30

  (integer) 1

  127.0.0.1:6379 ttl name

  (integer) 25

  127.0.0.1:6379

  关于 Redis 设定过期时间(这里包含过期键的删除)需要知道:

  Redis 对于设定过期时间的键是怎么保存的

  Redis 键的过期删除策略

  数据结构的选择

  Redis 常用的数据结构一共有五种:string、hash、list、set、zset(sorted set)。可以发现,大多数场景下使用 string 都可以去解决问题。但是,这并不一定是最优的选择。下面,简单说明下它们各自的适用场景:

  string:单个的缓存结果,不与其他的 KV 之间有联系

  hash:一个 Object 包含有很多属性,且这些属性都需要单独存储。注意:这种情况不要使用 string,因为 string 会占据更多的内存

  list:一个 Object 包含很多数据,且这些数据允许重复、要求有顺序性

  set:一个 Object 包含很多数据,不要求数据有顺序,但是不允许重复

  zset:一个 Object 包含很多数据,且这些数据自身还包含一个权重值,可以利用这个权重值来排序

  另外,Redis 还提供了一些特别的数据结构,用于一些特殊的场景。例如:Geo、HyperLogLog

  Geo:LBS 相关的应用,可以参考:Redis Geo

  HyperLogLog:允许存在误差的基数统计,可以参考:Redis HyperLogLog

  持久化机制的选择

  Redis 提供了两种持久化机制:RDB 和 AOF。

  RDB:在指定的时间间隔内将内存中的数据快照写入磁盘,实际操作过程是 fork 一个子进程,先将数据写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储

  AOF:以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录

  关于这两种持久化方式的优点不做解释,可以根据其实现形式得出结论。下面,分析下它们各自的缺点。

  RDB 的缺点

  如果你想保证数据的高可用性,即最大限度的避免数据丢失,那么 RDB 将不是一个很好的选择。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失

  由于 RDB 是通过 fork 子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟

  AOF 的缺点

  对于相同数量的数据而言,AOF 文件通常要大于 RDB 文件。RDB 在恢复大数据时的速度比 AOF 的恢复速度要快

  由于同步策略的不同,AOF 在运行效率上往往会慢于 RDB

  总结:二者选择的标准,就是看系统是愿意牺牲一些性能,换取更高的缓存一致性(AOF),还是愿意写操作频繁的时候,不启用备份来换取更高的性能。

  不要使用 Redis 存储单 Key 大数据

  这里所说的大数据,不是说不使用 Redis 存储更多的数据,而是说单个 KV 很大的情况。这里最核心的原因是:Redis 是单进程单线程的应用。这种工作方式在操作过程上避免了线程切换的耗时,而且不需要考虑线程安全,无需获取锁、释放锁等操作,是非常简单、直接的。但是:

  Redis 的单线程工作机制,无法用多核并行处理。如果遇到 IO 量大的操作,出现等待 IO 的情况会增多,即使 Redis 底层用的是 IO 多路复用技术,IO 的事件句柄也是要占用资源的

  Redis 的持久化需要将数据保存下来,KV 的数据量很大,也会影响持久化的执行

优化 Redis 的使用策略的更多相关文章

  1. CentOS的Redis内存分配策略配置

    安装了一主两从节点,启动之后发现有一个警告: 大概是说overcommit_memory设置成了0,在低内存环境下后台保存可能会失败,设置成1重启可解决. 然后,不太懂这个配置的含义,google一把 ...

  2. Redis淘汰删除策略

    Redis淘汰删除策略 Redis淘汰删除策略6种淘汰Key策略3种删除过期键策略定时删除惰性删除定期删除其他模块的淘汰处理RDB 快照持久化创建载入AOF 只追加持久化写入重写主从复模式下对过期键的 ...

  3. 面试官:讲讲redis的过期策略如何实现?

    时隔多日,小菜鸡终于接到阿里的面试通知,屁颠屁颠的从上海赶到了杭州. 经过半个小时的厮杀: 自我介绍 hashMap和ConcurrentHashMap区别 jdk中锁的实现原理 volatile的使 ...

  4. 深入剖析 redis AOF 持久化策略

    本篇主要讲的是 AOF 持久化,了解 AOF 的数据组织方式和运作机制.redis 主要在 aof.c 中实现 AOF 的操作. 数据结构 rio redis AOF 持久化同样借助了 struct ...

  5. redis 的过期策略都有哪些?内存淘汰机制都有哪些?

    面试题 redis 的过期策略都有哪些?内存淘汰机制都有哪些?手写一下 LRU 代码实现? 面试官心理分析 如果你连这个问题都不知道,上来就懵了,回答不出来,那线上你写代码的时候,想当然的认为写进 r ...

  6. redis的过期策略都有哪些?

    1.面试题 redis的过期策略都有哪些?内存淘汰机制都有哪些?手写一下LRU代码实现? 2.面试官心里分析 1)老师啊,我往redis里写的数据怎么没了? 之前有同学问过我,说我们生产环境的redi ...

  7. Redis的过期策略和内存淘汰策略(转)

    Redis的过期策略 我们都知道,Redis是key-value数据库,我们可以设置Redis中缓存的key的过期时间.Redis的过期策略就是指当Redis中缓存的key过期了,Redis如何处理. ...

  8. Redis的过期策略和内存淘汰策略

    Redis的过期策略:通常有三种,Redis中同时使用惰性过期和定期过期两种过期策略组合. 定时过期:每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除.该策略可以立即清除过期的数据 ...

  9. redis lru实现策略

    转载自http://blog.chinaunix.net/uid-20708886-id-5753422.html 在使用redis作为缓存的场景下,内存淘汰策略决定的redis的内存使用效率.在大部 ...

随机推荐

  1. jvm的内存模型

    转自:https://www.cnblogs.com/dingyingsi/p/3760447.html 我们知道,计算机CPU和内存的交互是最频繁的,内存是我们的高速缓存区,用户磁盘和CPU的交互, ...

  2. 修改bootstrap 的全局样式,bootstrap 3.0 是由html5和CSS 3组成的

    方法一: 不建议使用 * {}选择器,因为在一些其他样式插件.特殊部分会有更好的字体样式设定,用*就会全部覆盖. 正常引入bootstrap的css样式后,记得将自定义的样式表放到其之后, <l ...

  3. LinearLayout学习笔记

    线性布局分两种,分别是水平线性布局和垂直线性布局,对应设置为android:orientation="horizontal"/"vertical". Linea ...

  4. pta 习题集5-17 哥尼斯堡的“七桥问题”

    哥尼斯堡是位于普累格河上的一座城市,它包含两个岛屿及连接它们的七座桥,如下图所示. 可否走过这样的七座桥,而且每桥只走过一次?瑞士数学家欧拉(Leonhard Euler,1707-1783)最终解决 ...

  5. MAC OSX

    你可以输入下面的命令来查看IPv4端口:(最好加 sudo) # lsof -Pnl +M -i4

  6. float和double

    Java中,使用Float.floatToRawIntBits()函数获得一个单精度浮点数的IEEE 754 表示,例如: float fNumber = -5; //获得一个单精度浮点数的IEEE ...

  7. android中的验证码倒计时

    1.如图所示,要实现一个验证码的倒计时的效果                             2.实现 图中获取验证码那块是一个button按钮 关键部分,声明一个TimeCount,继承自C ...

  8. 【JEECG技术博文】JEECG表单配置-树形表单

    表单配置支持树型表单了,详细效果例如以下图:

  9. LoadRunner-常用的函数

    LoadRunner中,常用的函数有很多,这里只介绍编写性能测试脚本过程中那些必然用到的函数.本文重点关注这些典型函数的应用场合及注意点,至于函数详细使用说明请参见LoadRunner帮助文档. 1. ...

  10. 001-jpa基本概念以及基础注解

    一.什么是JPA JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中. S ...