导读:本文介绍在使用 Redis 过程中我们需要关注的两个主要方面:QPS、内存
在实际使用Redis过程中我们需要关注两点:
-
QPS,即Redis每秒处理请求数。Redis作为单线程架构服务,如果发生阻塞将是致命的。 -
内存,Redis作为内存数据库,考虑到内存价格昂贵,如何充分合理的使用内存,是Redis使用者必须考虑的问题。本节,将就这两个问题做重点分析。
阻塞
我们知道,Redis是典型单线程架构。这种架构下,所有的读写命令操作都是由主线程完成。主线程的处理能力将决定着Redis整体的性能。那么,哪些因素会导致Redis阻塞呢?
Redis自身因素
Redis本身的架构设计会是导致阻塞的潜在原因。
HGETALL
一个上百万feild
的hash
会导致Redis主进程阻塞数秒。-
图-1 Latency Numbers Every Programmer Should Know
对于持久化,有如下三点会导致阻塞:
fork
子进程。Redis主进程调用fork
系统调用产生子进程,由子进程负责完成持久化和重新工作,如果fork
本身过长,将会导致主进程阻塞。aof_buf
数据同步到磁盘磁盘上是由后台线程来完成的,由于涉及磁盘操作,当磁盘压力过大,后台线程在执行fsync
时,可能需要等待,直到写入完成。当主线程发现距离上次fsync
成功时间超过2s将会阻塞起来,直到fsync
完成。环境因素
内存
Redis最大的特性就是数据都在内存中,那么如何合理的规划这些数据就至关重要了。
Redis 内存消耗
Redis内存消耗主要包括:
key
和value
,可以简单理解为sizeof(key) + sizeof(value)
;client-output-buffer-limit
控制。主要包括:普通客户端、从客户端、订阅客户端)、复制积压缓冲区(Redis 2.8版本之后提供了一个固定大小的、用户复制功能的缓冲区,根据repl-backlog-size
控制,默认1MB)、AOF缓冲区(此缓冲区用于AOF重写期间写入命令);fork
子进程消耗内存。其中,1~3之和是used_memory
,4是used_memory_rss-used_memory
Redis 内存回收
有两个场景会触发内存回收:
-2
;maxmemory
触发数据淘汰,支持如下删除策略:-
noeviction
,默认策略,不删除任何数据; -
volation-lru
,对设置了过期时间的数据,通过模拟LRU算法进行删除,直到获取足够空间(线上使用策略); -
allkeys-lru
,对所有数据,通过模拟LRU算法进行删除,直到获取足够空间; -
allkeys-random
,对全体数据进行随机删除,直到获取足够空间; -
valatile-random
,对设置了过期时间的数据进行随机删除,直到获取足够空间; -
valatile-ttl
,根据数据TTL
属性,删除最近要过期的数据,如果没有则相当于noeviction
redisObject对象
Redis所有对象在内部都定义为redisObject
结构体,如代码-1。通过代码-1可知,一个redisObject
结构体需要占16B。Redis存储的所有数据类型(如string
、hash
、list
、set
、zset
等)都通过redisObject
来封装。结合前面数据结构小结,我们可知同一种数据结构至少有两种编码方式,不同的编码需要使用的存储空间是不同,如何合理地使用数据结构和编码将影响到存储空间的使用效率。
// redis-5.0.0 src/server.h 602
typedef struct redisObject {
unsigned type:4; // 对象类型 4bits
unsigned encoding:4; // 编码类型 4bits
unsigned lru:LRU_BITS; // LRU计时器 24bits
int refcount; // 引用计数 32bits
void *ptr; // 数据指针 64bits
} robj;
代码-1 redisObject 结构体
reference
原文始发于微信公众号(闲余说):使用Redis时我们主要关注啥
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/71148.html