赞
踩
redis是一个非常耗费内存的数据库,它的所有数据都放在内存里。如果我们不注意节约使用内存,redis就可能出现内存不足,最终导致崩溃。redis为了优化数据结构的内存占用,也加了非常多的优化点,这些优化也是以牺牲代码可读性为代价的。但是,这是非常值得的,尤其是像redis这种数据库。
redis如果使用32bit进行编译,内部所有数据结构所使用的指针空间占用会少一半,如果你的redis使用内存不超过4GB,可以考虑使用32bit进行编译,能够节约大量内存。如果不足还可以通过增加实例来解决
如果redis内部管理的集合数据结构很小,它会使用紧凑存储形式存储压缩
redis的ziplist是一个紧凑的字节数组结构,如下图,每个元素之间都是紧挨着的
如果它存储的是hash结构,那么key和value会作为两个entry被相邻存储
如果它存储的是zset结构,那么value和score会作为两个entry被相邻存储
redis的inset是一个紧凑的整数数组结构,用于存放元素都是整数而且元素个数比较少的set集合
如果set里存储的是字符串,那么sadd会升级为hashtable结构
下面说下存储界限。当集合对象的元素不断增加,或者某个value值过大,这种小对象存储也会被升级为标准结构。redis规定小对象存储结构的限制条件如下:
redis并不总是将空闲内存立即归还给操作系统
如果当前redis的内存有10GB,当你删除了1GB的key后,再去观察内存,你会发现内存变化不会太大。原因是操作系统是以页的单位来回收内存的,这个也上只要还有一个key在使用,那么它就不能被回收。redis虽然删除了1GB的key,但是这些key分散到了很多页面中,每个页面都还有其他key存在,这就导致了内存不会被立即回收
不过,入股你执行flushdb,然后再观察内存,会发现内存确实回收了。原因是所有的key都被干掉了,大部分之前使用的页面都完全干净了,就会立即被操作系统回收
redis虽然无法保证立即回收已经删除的key的内存,但是它会重新使用那些尚未回收的空闲内存。
内存分配是一个非常复杂的课题,需要适当的算法划分内存页,需要考虑内存碎片,需要平衡性能和效率
redis为了保证自身结构的简单性,在内存分配方面直接做了甩手掌柜,将内存分配的细节丢给了第三方内存分配库实现,默认使用jemalloc(facebook)库来管理内存,也可以切换到tcmalloc(google)库
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。