优化 Redis 的使用策略
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 的使用策略的更多相关文章
- CentOS的Redis内存分配策略配置
安装了一主两从节点,启动之后发现有一个警告: 大概是说overcommit_memory设置成了0,在低内存环境下后台保存可能会失败,设置成1重启可解决. 然后,不太懂这个配置的含义,google一把 ...
- Redis淘汰删除策略
Redis淘汰删除策略 Redis淘汰删除策略6种淘汰Key策略3种删除过期键策略定时删除惰性删除定期删除其他模块的淘汰处理RDB 快照持久化创建载入AOF 只追加持久化写入重写主从复模式下对过期键的 ...
- 面试官:讲讲redis的过期策略如何实现?
时隔多日,小菜鸡终于接到阿里的面试通知,屁颠屁颠的从上海赶到了杭州. 经过半个小时的厮杀: 自我介绍 hashMap和ConcurrentHashMap区别 jdk中锁的实现原理 volatile的使 ...
- 深入剖析 redis AOF 持久化策略
本篇主要讲的是 AOF 持久化,了解 AOF 的数据组织方式和运作机制.redis 主要在 aof.c 中实现 AOF 的操作. 数据结构 rio redis AOF 持久化同样借助了 struct ...
- redis 的过期策略都有哪些?内存淘汰机制都有哪些?
面试题 redis 的过期策略都有哪些?内存淘汰机制都有哪些?手写一下 LRU 代码实现? 面试官心理分析 如果你连这个问题都不知道,上来就懵了,回答不出来,那线上你写代码的时候,想当然的认为写进 r ...
- redis的过期策略都有哪些?
1.面试题 redis的过期策略都有哪些?内存淘汰机制都有哪些?手写一下LRU代码实现? 2.面试官心里分析 1)老师啊,我往redis里写的数据怎么没了? 之前有同学问过我,说我们生产环境的redi ...
- Redis的过期策略和内存淘汰策略(转)
Redis的过期策略 我们都知道,Redis是key-value数据库,我们可以设置Redis中缓存的key的过期时间.Redis的过期策略就是指当Redis中缓存的key过期了,Redis如何处理. ...
- Redis的过期策略和内存淘汰策略
Redis的过期策略:通常有三种,Redis中同时使用惰性过期和定期过期两种过期策略组合. 定时过期:每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除.该策略可以立即清除过期的数据 ...
- redis lru实现策略
转载自http://blog.chinaunix.net/uid-20708886-id-5753422.html 在使用redis作为缓存的场景下,内存淘汰策略决定的redis的内存使用效率.在大部 ...
随机推荐
- mac必装工具以及mac使用介绍
必装工具 Scroll Reverserhttp://pilotmoon.com/scrollreverser/:一款可以使得鼠标使用方式和windows系统一致的软件 编程工具 ,,,,, 常用快捷 ...
- 豆瓣api开发
前面有说过豆瓣API的开发,在做一些开源项目的时候,很多时候会用到豆瓣API接口,拿过来做测试,现在只是对豆瓣API开发做一些简单的梳理: 豆瓣API开发的接口: https://developers ...
- linux中增加swap分区文件的步骤方法
一.swap交换分区 Swap分区在系统的物理内存不够用的时候,把硬盘空间中的一部分空间释放出来,以供当前运行的程序使用.那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临 ...
- 容斥原理解决某个区间[1,n]闭区间与m互质数数量问题
首先贴出代码(闭区间[1,n]范围内和m互质的数) 代码: int solve(II n,II m){ vector<II>p; ;i*i<=m;i++){ ){ p.push_ba ...
- RSA算法原理与加密解密 求私钥等价求求模反元素 等价于分解出2个质数 (r*X+1)%[(p-1)(q-1)]=0
Rsapaper.pdf http://people.csail.mit.edu/rivest/Rsapaper.pdf [概述Abstract 1.将字符串按照双方约定的规则转化为小于n的正整数m, ...
- collision weaknesses
15.1. hashlib — Secure hashes and message digests — Python 3.5.6 documentation https://docs.python.o ...
- 如何在window的location使用target
在页面中window的location跳转时,指定页面在框架中跳转 1. 如果你要让最顶层的框架跳转,就是整个页面,相当于用traget指向顶层 window.top.location = & ...
- java 并查集
并查集代码 并查集优化⼀ 并查集优化⼆ 实战题⽬目1. https://leetcode.com/problems/number-of-islands/2. https://leetcode.com/ ...
- shell 环境变量的知识小结
环境变量的知识小结:·变量名通常要大写.·变量可以在自身的Shell及子Shell中使用.·常用export来定义环境变量.·执行env默认可以显示所有的环境变量名称及对应的值.·输出时用“$变量名” ...
- centos HA高可用集群 heartbeat搭建 heartbeat测试 主上停止heartbeat服务 测试脑裂 两边都禁用ping仲裁 第三十二节课
centos HA高可用集群 heartbeat搭建 heartbeat测试 主上停止heartbeat服务 测试脑裂 两边都禁用ping仲裁 第三十二节课 heartbeat是Linu ...