美文网首页程序员
降低Redis内存的占用

降低Redis内存的占用

作者: 志华_C | 来源:发表于2017-09-18 07:48 被阅读0次

1.原理

短结构

Redis为列表、集合、散列和有序集合提供了一组配置选项,让Redis以跟节约内存的方式存储这些变量

阿里云主从版提供的选项(全是和短结构有关的,ziplist可以说是除了hash字典之外最常用的结构)

image

在列表、散列、有序集合的长度较短或者体积较小的时候,redis会使用压缩列表(ziplist)代替通常情况下这三种结构的底层实现方式作为这几种结构的底层实现。

配置:

  • entries:最大元素数量
  • value:压缩列表的每个节点的最大体积

当任一条件被突破时,Redis就会把底层实现改为通常的结构,而且当数据被删除之后也不会再次使用ziplist

体积较小的集合使用intset来作为底层实现

条件:

  • 整数集合包含的所有成员都可以被解释为十进制数
  • 这些整数又处于平台的有符号整数范围之内
  • 集合成员数量足够少

短结构是以上几种结构的紧凑表示方式

减少键的长度也是应该注意的一个点。

短结构ziplist

Redis中ziplist的定义(序列化字符串)和接口

unsigned char *ziplistNew(void);
unsigned char *ziplistPush(unsigned char *zl, unsigned char *s, unsigned int slen, int where);
unsigned char *ziplistIndex(unsigned char *zl, int index);
unsigned char *ziplistNext(unsigned char *zl, unsigned char *p);
unsigned char *ziplistPrev(unsigned char *zl, unsigned char *p);
unsigned int ziplistGet(unsigned char *p, unsigned char **sval, unsigned int *slen, long long *lval);
unsigned char *ziplistInsert(unsigned char *zl, unsigned char *p, unsigned char *s, unsigned int slen);
unsigned char *ziplistDelete(unsigned char *zl, unsigned char **p);
unsigned char *ziplistDeleteRange(unsigned char *zl, unsigned int index, unsigned int num);
unsigned int ziplistCompare(unsigned char *p, unsigned char *s, unsigned int slen);
unsigned char *ziplistFind(unsigned char *p, unsigned char *vstr, unsigned int vlen, unsigned int skip);
unsigned int ziplistLen(unsigned char *zl);
size_t ziplistBlobLen(unsigned char *zl);

压缩列表由节点序列和四个控制位组成。

影响性能的因素:每次读取数据时都需要对进行解码,写入也需要进行局部的重新编码,并且有可能触发连锁更新,但是这些操作在对小列表进行处理时对性能的损耗并不很明显(平均O(N))。

短结构intset

Redis中整数集合的定义和接口,可见其最底层实现就是一个有序的C语言数组。

typedef struct intset {
    
    // 编码方式
    uint32_t encoding;

    // 集合包含的元素数量
    uint32_t length;

    // 保存元素的数组
    int8_t contents[];

} intset;

intset *intsetNew(void);
intset *intsetAdd(intset *is, int64_t value, uint8_t *success);
intset *intsetRemove(intset *is, int64_t value, int *success);
uint8_t intsetFind(intset *is, int64_t value);
int64_t intsetRandom(intset *is);
uint8_t intsetGet(intset *is, uint32_t pos, int64_t *value);
uint32_t intsetLen(intset *is);
size_t intsetBlobLen(intset *is);

影响性能的因素:对整数集合进行插入或者删除操作时需要进行数据移动,并有可能引起底层升级。

随着短结构的体积变得越来越大,操作这些结构的速度也会变得越来越慢,所以可以引入分片技术以追求性能和空间之前的平衡。

2.分片结构

  • 特别适合分片的场景:执行分片版命令的时候只需要访问指定分片即可。
  • 特别不适合分片的场景:需要访问指定分片,完事还得进行归并聚合的操作。
  • 可以通过分片提升性能的场景:搜索
  • 替代分片的一种场景:只对前n位和后n位操作的有序集合(用单独维护的两个最大有序集合和最小有序集合实现)。
  1. 对列表进行分片

  2. 有序集合进行分片:
    有序集合的大部分操作都属于特别不适合分片的场景。

  3. 分片式散列:将字符串键存储到散列里面也可以明显降低内存占用

    1. 实现分片方法即可
asbtract class ShardHlist { 
/*
** $base 基础散列 
** $key 将要保存到分片散列里面的键
** $total_elements 预计元素总量
** $shard_size 预期分片大小
*/
abstract public function shard_key($base, $key, $total_elements, $shard_size);
abstract public function shard_hset($shard_key, key, value, $total_elements, $shard_size);
abstract public function shard_hset($shard_key, key, $total_elements, $shard_size);
}

如果不是辅助缓存那么不应该随便更改$total_elements 和 $shard_size,一旦不得不更改需要resharding方法将数据从旧的分片迁移到新的分片

  1. 分片集合
    shard_add、shard_rem

3.二进制位和字节打包用来进一步降低存储空间

相关文章

  • Redis短结构与分片方式

    本文将介绍两种降低Redis内存占用的方法——使用短结构存储数据和对数据进行分片。降低Redis内存占用有助于减少...

  • Redis降低内存占用

    1.Redis降低内存占用方案 短结构 分片结构 2.短结构 2.1 压缩列表 以列表为例,列表是由双向链表实现,...

  • 降低Redis内存的占用

    1.原理 短结构 Redis为列表、集合、散列和有序集合提供了一组配置选项,让Redis以跟节约内存的方式存储这些...

  • redis内存优化的探索和实践

    1,redis如何管理内存结构 redis内存模型: 【used_memory】:Redis内存占用中最主要的部分...

  • Redis 实战 —— 12. 降低内存占用

    简介 降低 Redis 的内存占用有助于减少创建快照和加载快照所需的时间、提升载入 AOF 文件和重写 AOF 文...

  • Redis 内存

    Redis 占用内存的大小 使用 redis-cli 登录到 Redis Server,执行 info 命令, ...

  • 如何查看redis占用内存大小

    如何查看redis占用内存大小 redis缓存固然高效,可是它会占用我们系统中宝贵的内存资源,特别是当我们的项目运...

  • Fragment使用过程中遇到过的坑

    使用Fragment可以让APP更加的流畅,并且降低内存占用,同样的界面Activity占用内存比Fragment...

  • Android降低内存占用

    1、图片的内存占用;内存缓存大小控制2、强引用 弱引用 软引用3、减少不一样的全局变量4、避免创建不必要的对象5、...

  • Android-Bitmap压缩总结

    Bitmap占用内存 = 长 X 宽 X 1个像素所占字节,降低任意参数就可减少Bitmap占用内存! 一、质量压...

网友评论

    本文标题:降低Redis内存的占用

    本文链接:https://www.haomeiwen.com/subject/fjrmsxtx.html