开发者社区官方技术圈

阿里云开发者社区官方技术圈,用户产品功能发布、用户反馈收集等。

阿里云开发者社区官方技术圈,用户产品功能发布、用户反馈收集等。

当Redis在执行后台RDB,采用fork子进程的方式来处理。但主进程fork子进程后,此时的主进程依旧是可以接收写请求的,而进来的写请求,会采用Copy On Write(写时复制)的方式操作内存数据。也就是说,主进程一旦有数据需要修改,Redis并不会直接修改现有内存中的数据,而是先将这块内存数据拷贝出来,再修改这块新内存的数据,这就是所谓的「写时复制」。

写时复制你也可以理解成,谁需要发生写操作,谁就需要先拷贝,再修改。这样做的好处是,父进程有任何写操作,并不会影响子进程的数据持久化(子进程只持久化fork这一瞬间整个实例中的所有数据即可,不关心新的数据变更,因为子进程只需要一份内存快照,然后持久化到磁盘上)。

但是请注意,主进程在拷贝内存数据时,这个阶段就涉及到新内存的申请,如果此时操作系统开启了内存大页,那么在此期间,客户端即便只修改10B的数据,Redis在申请内存时也会以2MB 为单位向操作系统申请,申请内存的耗时变长,进而导致每个写请求的延迟增加,影响到Redis性能。

同样地,如果这个写请求操作的是一个bigkey,那主进程在拷贝这个bigkey内存块时,一次申请的内存会更大,时间也会更久。可见,bigkey在这里又一次影响到了性能。以上内容摘自《阿里开发者手册-Redis专题》电子书,点击https://developer.aliyun.com/ebook/download/7770 可下载完整版

游客c3gxxcx6cqeyo 评论 0

当Redis内存达到maxmemory后,每次写入新的数据之前,Redis必须先从实例中踢出一部分数据,让整个实例的内存维持在maxmemory之下,然后才能把新数据写进来。

这个踢出旧数据的逻辑也是需要消耗时间的,而具体耗时的长短,要取决于你配置的淘汰策略:

•allkeys-lru:不管key是否设置了过期,淘汰最近最少访问的key; •volatile-lru:只淘汰最近最少访问、并设置了过期时间的key; •allkeys-random:不管key是否设置了过期,随机淘汰key; •volatile-random:只随机淘汰设置了过期时间的key; •allkeys-ttl:不管key是否设置了过期,淘汰即将过期的key; •noeviction:不淘汰任何key,实例内存达到maxmeory后,再写入新数据直接返回错误; •allkeys-lfu:不管key是否设置了过期,淘汰访问频率最低的key(4.0+版本支持); •volatile-lfu:只淘汰访问频率最低、并设置了过期时间key(4.0+版本支持)。

一般最常使用的是allkeys-lru/volatile-lru淘汰策略,它们的处理逻辑是,每次从实例中随机取出一批key(这个数量可配置),然后淘汰一个最少访问的key,之后把剩下的key暂存到一个池子中,继续随机取一批key,并与之前池子中的key比较,再淘汰一个最少访问的key。以此往复,直到实例内存降到maxmemory之下。

需要注意的是,Redis的淘汰数据的逻辑与删除过期key的一样,也是在命令真正执行之前执行的,也就是说它也会增加我们操作Redis的延迟,而且,写OPS越高,延迟也会越明显。以上内容摘自《阿里开发者手册-Redis专题》电子书,点击https://developer.aliyun.com/ebook/download/7770 可下载完整版

游客c3gxxcx6cqeyo 评论 0

公告

阿里云开发者社区官方技术圈,用户产品功能发布、用户反馈收集等。

展开