Memcached与Redis(三)

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介:

3. Memcached和Redis关键技术对比

作为内存数据缓冲系统,Memcached和Redis均具有很高的性能,但是两者在关键实现技术上具有很大差异,这种差异决定了两者具有不同的特点和不同的适用条件。下面我们会对两者的关键技术进行一些对比,以此来揭示两者的差异。

3.1 Memcached和Redis的内存管理机制对比

对于像Redis和Memcached这种基于内存的数据库系统来说,内存管理的效率高低是影响系统性能的关键因素。传统C语言中的malloc/free函数是最常用的分配和释放内存的方法,但是这种方法存在着很大的缺陷:首先,对于开发人员来说不匹配的malloc和free容易造成内存泄露;其次,频繁调用会造成大量内存碎片无法回收重新利用,降低内存利用率;最后,作为系统调用,其系统开销远远大于一般函数调用。所以,为了提高内存的管理效率,高效的内存管理方案都不会直接使用malloc/free调用。Redis和Memcached均使用了自身设计的内存管理机制,但是实现方法存在很大的差异,下面将会对两者的内存管理机制分别进行介绍。

3.1.1 Memcached的内存管理机制

Memcached默认使用Slab Allocation机制管理内存,其主要思想是按照预先规定的大小,将分配的内存分割成特定长度的块以存储相应长度的key-value数据记录,以完全解决内存碎片问题。Slab Allocation机制只为存储外部数据而设计,也就是说所有的key-value数据都存储在Slab Allocation系统里,而Memcached的其它内存请求则通过普通的malloc/free来申请,因为这些请求的数量和频率决定了它们不会对整个系统的性能造成影响

Slab Allocation的原理相当简单。 如图3所示,它首先从操作系统申请一大块内存,并将其分割成各种尺寸的块Chunk,并把尺寸相同的块分成组Slab Class。其中,Chunk就是用来存储key-value数据的最小单位。每个Slab Class的大小,可以在Memcached启动的时候通过制定Growth Factor来控制。假定Figure 1中Growth Factor的取值为1.25,所以如果第一组Chunk的大小为88个字节,第二组Chunk的大小就为112个字节,依此类推。

谈谈Memcached与Redis(三)

图3 Memcached内存管理架构

当Memcached接收到客户端发送过来的数据时首先会根据收到数据的大小选择一个最合适的Slab Class,然后通过查询Memcached保存着的该Slab Class内空闲Chunk的列表就可以找到一个可用于存储数据的Chunk。当一条数据库过期或者丢弃时,该记录所占用的Chunk就可以回收,重新添加到空闲列表中。从以上过程我们可以看出Memcached的内存管理制效率高,而且不会造成内存碎片,但是它最大的缺点就是会导致空间浪费。因为每个Chunk都分配了特定长度的内存空间,所以变长数据无法充分利用这些空间。如图 4所示,将100个字节的数据缓存到128个字节的Chunk中,剩余的28个字节就浪费掉了。

谈谈Memcached与Redis(三)
图4 Memcached的存储空间浪费

3.1.2 Redis的内存管理机制

Redis的内存管理主要通过源码中zmalloc.h和zmalloc.c两个文件来实现的。Redis为了方便内存的管理,在分配一块内存之后,会将这块内存的大小存入内存块的头部。如图 5所示,real_ptr是redis调用malloc后返回的指针。redis将内存块的大小size存入头部,size所占据的内存大小是已知的,为size_t类型的长度,然后返回ret_ptr。当需要释放内存的时候,ret_ptr被传给内存管理程序。通过ret_ptr,程序可以很容易的算出real_ptr的值,然后将real_ptr传给free释放内存。

谈谈Memcached与Redis(三)

图5 Redis块分配

Redis通过定义一个数组来记录所有的内存分配情况,这个数组的长度为ZMALLOC_MAX_ALLOC_STAT。数组的每一个元素代表当前程序所分配的内存块的个数,且内存块的大小为该元素的下标。在源码中,这个数组为zmalloc_allocations。zmalloc_allocations[16]代表已经分配的长度为16bytes的内存块的个数。zmalloc.c中有一个静态变量used_memory用来记录当前分配的内存总大小。所以,总的来看,Redis采用的是包装的mallc/free,相较于Memcached的内存管理方法来说,要简单很多。


















本文转自liujing0751CTO博客,原文链接:http://blog.51cto.com/13281352/1981038 ,如需转载请自行联系原作者


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
4月前
|
缓存 NoSQL 应用服务中间件
2.2.2 redis,memcached,nginx网络组件
2.2.2 redis,memcached,nginx网络组件
|
4月前
|
NoSQL Java 应用服务中间件
4.网络设计与redis、memcached、nginx组件(二)
4.网络设计与redis、memcached、nginx组件(二)
28 0
|
4月前
|
存储 NoSQL 应用服务中间件
4.网络设计与redis、memcached、nginx组件(一)
4.网络设计与redis、memcached、nginx组件(一)
76 0
|
3月前
|
缓存 NoSQL Redis
如何在Python中使用Redis或Memcached进行缓存?
如何在Python中使用Redis或Memcached进行缓存?
28 2
|
4月前
|
缓存 NoSQL Java
flea-cache使用之整合Memcached和Redis接入
【1月更文挑战第3天】本篇博文介绍 flea框架下的 flea-cache 模块中 整合接入 Memcached 和 Redis
51 1
flea-cache使用之整合Memcached和Redis接入
|
4月前
|
NoSQL 关系型数据库 应用服务中间件
redis,memcached,nginx网络组件,网络编程——reactor的应用
目标 明白网络模块要处理那些事情 reactor 是怎么处理这些事情的 reactor 如何封装的 网络模块与业务逻辑的关系 如何优化 reactor 网络编程关注的问题
49 1
|
4月前
|
NoSQL 网络协议 应用服务中间件
redis,memcached,nginx网路组件
redis,memcached,nginx网路组件
39 0
|
5月前
|
Linux Memcache
Linux - 安装memcached
Linux - 安装memcached
49 0
Linux - 安装memcached
|
6月前
|
Docker 容器
Docker下安装memcached
Docker下安装memcached
53 0
|
9月前
|
Shell C语言
脚本用源码来安装 memcached 服务器
脚本用源码来安装 memcached 服务器
34 1