小对象压缩

  • Redis是一种内存数据库,内存是计算机中一种比较宝贵的资源,如果我们不注意节约,Redis很可能出现内存不足,最终导致崩溃。Redis为了优化数据结构的内存占用,增加了非常多的优化点,这些优化也是牺牲代码的可读性为代价,但是对于解决的内存问题来说是非常值得的,尤其是对于Redis这种内存数据库
32bit VS 64bit
  • Redis如果使用32bit版本,内部存储所有数据结构使用的指针空间占用会少一半,如果Redis使用内存不会超过2^32 = 4GB,可以考虑32bit进行编译,能节约大量内存。4GB容量对小站点来说戳戳由于。不足可以增加节点

    • 指针是寻址,存储的是地址信息,32bit系统能表示的总大小是2^32 位,所以指针能表示的寻址最大值也就是 2 ^32,同理64bit 系统占用2 ^ 64
小对象压缩
  • 如果Redis内部管理的集合数据结构很小,他会使用紧凑型存储形式压缩存储,只有当集合数据达到一定量级的时候,Redis才会将数据存储称为正常我们熟知的状态。
  • 例如HashMap本来是二维结构,如果内部元素少,使用数组+链表的形式反而浪费空间,因为指针占用空间比数据还要多,还不如使用一维数组进行存储,查找时候元素少,遍历也快,只不过代码略复杂而已。以下案例用一维数组存储HashMap的CUD
public class ArrayMap<K, V> {private List<K> keys = new ArrayList<>();private List<V> values = new ArrayList<>();public V put(K k, V v){for (int i = 0; i < keys.size(); i++) {if(keys.get(i).equals(k)){V oldv = values.get(i);values.set(i, v);return oldv;}}keys.add(k);values.add(v);return null;}public V get(K k){for (int i = 0; i < keys.size(); i++) {if(keys.get(i).equals(k)){return values.get(i);}}return null;}public V delete(K k){for (int i = 0; i < keys.size(); i++) {if(keys.get(i).equals(k)){keys.remove(k);return values.remove(i);}}return null;}
}
  • 同样Redis的ziplist是一个紧凑型的字节数组结构,如下图中所示,每个元素都是紧密相连,中间没有指针用来寻址操作,通过三个全局指针来完成逻辑处理,zlbytes, zltail和zlend。如下:
  • 如果如上结果存储的是hash结构,那么key和value作为两个entry,被相邻的两个entry存储,通过如下方式验证,输出类型是ziplist:
新docker-redis:0>hset hello a 1
"1"
新docker-redis:0>hset hello b 2
"1"
新docker-redis:0>object encoding hello
"ziplist"
  • 如果存储的类型是zset,那么value和score会作为两个entry被相邻存储
新docker-redis:0>zadd world 1 a
"1"
新docker-redis:0>zadd world 2 b
"1"
新docker-redis:0>object encoding world
"ziplist"
  • 整数的存储Redis有一个叫intset的整数数组结构,用于存放元素都是整数且元素个数较少的set集合。
  • 如果整数可以用uint16标识,那么intset的元素就是16位的数组,如果新加入的整数超过uint16,那么久用uint32,还不够则用uint64,Redis支持set集合动态从unit16升级到unit32,在到unit64

  • 如下代码,我们在set集合中存储的数字,他的类型就是intset
新docker-redis:0>sadd hello 1 2
"2"
新docker-redis:0>object encoding hello
"intset"
  • 如果set存储的字符串,那么sadd会升级为hashtable结构,
新docker-redis:0>sadd hello yes no
"2"
新docker-redis:0>object encoding hello
"hashtable"
总结
hash - max-z 工pl 工 st entries 512 结构存储           # hash 的元素个数超过 512 就必须用标准
hash- max-ziplist-value 64 超过 64 就必须用标准结构存储     # hash 的任意元素的 key/value 的长度超过64 就必须用标准结构存储
list-max-ziplist-entries 512 结构存储                   # list 的元素个数超过 512 就必须用标准结构存储
list-max-z 工plist - value 64 用标准结构存储            # list 的任意元素的长度超过 64 就必须用标准结构存储
zset-max-ziplist-entries 128 结构存储                   # zset 的元素个数超过 128 就必须用标准结构存储
zset-max- ziplist-value 64 用标准结构存储                  # zset 的任意元素的长度超过 64 就必须用标准结构存储
set-max-intset-entries 512 标准结构存储                   # set 的整数元素个数超过 512 就必须用标准结构存储
  • 如下测试代码:
public static void main(String[] args) {Jedis jedis = JedisPoolTools.getJedis();jedis.del("books");for (int i = 0; i < 512; i++) {jedis.hset("books", String.valueOf(i), String.valueOf(i));}System.out.println(jedis.objectEncoding("books"));jedis.hset("books", "hello", "512");System.out.println(jedis.objectEncoding("books"));}
//输出如下:
ziplist
hashtable
  • 当Hash结构元素超过512 ,存储结构发生变化其他的也都同理,我们通过如上总结数据看出,当hash结构的任意entry的value超过64 ,存储结构就升级成标准结构。
内存回收机制
  • Redis并不总是将空闲内存理解归还操作系统
  • 例如Redis内存10GB,当删除1GBkey后,观察内存,并不会太大变化,因为操作系统是以页为单位回收内存,这个页内只要还有一个key,就不会被回收。Redis虽然删除了1GBkey但是这些key是分散到各个page中,每个page都还有其他key,这就导致内不会被立刻回收。
  • 我们执行flushdb,观察内存,他就会重新使用那些尚未回收的空闲内存。就比如一个page中只有一个key,次数set另一个key,他会存储在这个page的空闲内存中。
内存分配算法
  • 内存分配是比较复杂的,需要是的划分内存页,考虑内存碎片,需要平衡性能与效率
  • Redis为保证自身结构简单,目前没有自己做内存分配策略,由第三方库完成此部分内容,
    • Redis可以用jemalloc,facebook的库来管理内存
    • Redis也可以切换到tcmalloc,google的库来管理
  • jemalloc性能优于tcmalloc,Redis默认使用jemalloc
新docker-redis:0>info memory
"# Memory
used_memory:5110711968
.....
mem_fragmentation_ratio:1.33
mem_allocator:jemalloc-4.0.3
active_defrag_running:0
lazyfree_pending_objects:0
  • 通过info memory指令可以看到Redis的 mem_allocator:jemalloc-4.0.3使用的jemalloc-4.0.3

上一篇:Redis–事务理解
下一篇:Redis高可用基石–主从同步

Redis存储优化--小对象压缩相关推荐

  1. Redis存储与取出对象

    Redis存储与取出对象 import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation. ...

  2. Redis 存储字符串和对象

    今天用redis存储,发现客户端jedis提供的存储方法中存储的类型只有String和byte数据,没有能够存储对象的,网上发现可以序列化存储对象.这就开始了我第一次序列化之旅. 1 测试类 impo ...

  3. redis存储与读取对象和对象集合

    在生产过程中经常会用到redis这种nosql数据存储,以达到快速的查询等操作. 在参考网上与相关图书资料后,决定自己动手实践以下redis对对象的存储与读取,以便以后在工作中可以拿来主意. redi ...

  4. redis 存储数组和对象

    首先要使用redis必须要安装redis并开启 将jedis-2.9.0.jar包加入项目 这是一个最简单的redis插入和读取 // 连接本地的 Redis 服务 Jedis jedis = new ...

  5. redis存储对象_redis内存优化总结

    本文主要参考<>一书,主要分为以下六个部分: 1.redisObject对象 2.缩减键值对象 3.共享对象池 4.字符串优化 5.编码优化 6.控制key的数量 一. redisObje ...

  6. 云存储之对象存储性价比小谈

    相信大家对云存储的优点都已经有所了解,例如云存储支持按需使用,按需付费,不必承担多余的开销,也无需增加额外的硬件设施或配备专人负责维护.正因为有如此多的优点,市场上云存储公司也如雨后春笋越来越多,但选 ...

  7. Redis 存储对象信息是用 Hash 还是 String

    Redis 内部使用一个 RedisObject 对象来表示所有的 key 和 value,RedisObject 中的 type,则是代表一个 value 对象具体是何种数据类型,它包含字符串(St ...

  8. java s3 与ceph的关系_Ceph存储与S3对象存储性能优化.pdf

    Ceph存储与S3对象存储性能优化.pdf Ceph on Storage appliance Case Study and Performance for AWS S3 based object s ...

  9. Redis 存储List对象

    如果需要用到Redis存储List对象,而list又不需要进行操作,可以按照MC的方式进行存储,不过Jedis之类的客户端没有提供API,可以有两种思路实现: 1.      分别序列化 elemen ...

最新文章

  1. 从命令行使用 wget 调试网页错误
  2. redis数据结构详解之Hash(四)
  3. 使用 Sealos + Longhorn 部署 KubeSphere v3.0.0
  4. 【LeetCode】LeetCode之跳跃游戏——动态规划+贪心算法
  5. 一分钟安装IDA pro7.0
  6. mvc的视图中显示DataTable的方法
  7. 关于android:windowNoTitle不起作用的解决办法
  8. win10电脑开机密码忘了怎么办_电脑开机密码忘了怎么办最简单的方法_windows7教程...
  9. 窗口潜水面罩行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  10. 454.四数相加II
  11. 全国2013年最新电子地图矢量数据超图格SGD MAPINFO GST SMW SHP格式等
  12. Word 文档中的图片另存为 .jpg 格式图片方法
  13. 前端传参日期只有年月日,后台给日期设置23时59分59秒和0时0分0秒
  14. Redis:Error starting userland proxy: listen tcp4 0.0.0.0:6379: bind: address already in use
  15. php 图片 圆角,PHP将图片处理成圆角
  16. 陈伊力:手游将会出现更多同步交互类游戏
  17. 在带头结点单链表中查找最大值,将其与最后一个元素交换(交换值)
  18. Thoth-Tech靶机实验实战演练
  19. 用python读取txt文件中的数据并画各类图形展示_Python实现读取txt文件中的数据并绘制出图形操作示例...
  20. 最老程序员创业开发实训2---采用MVC架构的应用Splash页面实现

热门文章

  1. SSH基本原理和免密码登录
  2. 用java写的常见排序
  3. SQL UNION 和 UNION ALL 操作符(mysql)
  4. 找不到libmmd.dll无法继续执行代码_300 行代码带你秒懂 Java 多线程!| 原力计划...
  5. 百般受虐!“波士屯动力”机器人这一次枪口对准人类
  6. 了解IT行业前沿应用,关注数据与算法之美
  7. 资料分享 | 数据挖掘实例资料分享来袭
  8. 计算机试题dddd,数据库系统概论试题及答案dddd_Image_Marked.pdf
  9. win10必须禁用的服务_【亲测】Win10系统如何彻底禁止自动更新 亲测有效的Win10关闭自动更新方法...
  10. spss22.0统计分析从入门到精通_数据分析最全资料:SPSS/MATLAB/SQL/SAS/EXCEL经典教材+视频教程,快速入门!...