关于作者,目前在蚂蚁金服搬砖任职,在支付宝营销投放领域工作了多年,目前在专注于内存数据库相关的应用学习,如果你有任何技术交流或大厂内推及面试咨询,都可以从我的个人博客(https://0522-isniceday.top/)联系我
按照业务用于区分key,使用冒号进行分割
这样能够将相同的业务key放到一个db,减少切换db的开销
规范的命令有利于key的匹配,keys命令。例如客户端缓存的key的监控、scan等操作
控制key的长度
Redis针对读写命令的处理是单线程的,因此bigkey的操作会阻塞线程,尤其是针对时间复杂度为O(n)的数据结构进行并交集、全量查询等耗时的操作
bigkey也分为两种:
Redis的4种集合类型List、Hash、Set和Sorted Set,在集合元素个数小于一定的阈值时,会使用内存紧凑型的底层数据结构(压缩列表)进行保存,从而节省内存。例如,假设Hash集合的hash-max-ziplist-entries配置项是1000,如果Hash集合元素个数不超过1000,就会使用ziplist保存数据。
但是,不同的序列化方法,在序列化速度和数据序列化后的占用内存空间这两个方面,效果是不一样的。比如说,protostuff和kryo这两种序列化方法,就要比Java内置的序列化方法(java-build-in-serializer)效率更高。
此外,业务应用有时会使用字符串形式的XML和JSON格式保存数据。
这样做的好处是,这两种格式的可读性好,便于调试,不同的开发语言都支持这两种格式的解析。
缺点在于,XML和JSON格式的数据占用的内存空间比较大。为了避免数据占用过大的内存空间,我建议使用压缩工具(例如snappy或gzip),把数据压缩后再写入Redis,这样就可以节省内存空间了
Redis内部维护了09999这一万个整数对象,并将其作为对象池使用,因此再业务允许的情况下,能用整数就用整数,因为如果使用到了整数,不管有多少键值对,其实真是的引用地址都是一个,这样可以大大的节省空间哟
但是整数共享池在某些场景不会起作用:
redis保存热数据能够提供高性能的访问,如果写场景比较多的话,也需要将数据同步的开销算进去,还有就是需要考虑
缓存失效导致的缓存击穿,因为尽量将数据不设置过期时间,还有就是可以将同步缓存的操作用分布式锁锁住,这样就不会有大量请求打向数据库了
把不同的业务数据放到不同的 Redis 实例中。这样一来,既可以避免单实例的内存使用量过大,也可以避免不同业务的操作相互干扰
根据业务的时长,设置合理的过期时间,因为如果不设置过期时间,redis实例内存满了会触发数据淘汰,这个时候会释放内存的操作会阻塞主进程,并且设置过期时间时候尽量避免批量过期的情况
建议设置在2~6GB,实例数据量过大会加大RDB快照的fork的耗时,以及主从实例数据同步的耗时
Redis是单线程处理读写命令,如果一些耗时的命令或操作会阻塞主进程,其中包括:
KEYS
:返回匹配key内容的key,这个操作会扫描全局哈希表,严重阻塞redis的主进程,可用SCAN命令进行替代FLUSHALL
,删除Redis实例上的所有数据,如果数据量很大,会严重阻塞Redis主线程,可以加上ASYNC,让redis后台线程异步删除FLUSHDB
,删除当前数据库中的数据,如果数据量很大,同样会阻塞Redis主线程,解决方案同FLUSHALL
线上如何禁用呢?管理员用rename-command命令在配置文件中对这个命令重命名,让客户端无法使用
Redis使用MONITOR命令后,会持续监控后续命令的执行情况,这个时候会将执行情况输入到输出缓存区,如果输出缓冲区满了之后就会影响Redis性能及造成redis崩溃
建议不使用MONITOR命令,除非十分需要监测某些命令的执行,可以短时间内使用
对于集合数据类型而言,慎重使用SCAN等操作,因为这些操作会对底层的数据进行全表扫描,如果数据量比较大则会阻塞主线程
解决方案如下:
强制:表示如果不遵守会给redis带来极大的性能影响
推荐:代表可以直接运用在实践中
建议:结合业务场景考量再决定是否使用