redis实战学习第六天
发表于:2025-03-06 | 分类: 学习

降低内存占⽤

短结构

Redis为列表、集合、散列和有序集合提供了⼀组配置选项,这些选项可以让Redis以更节约空间的⽅式存储长度较短的结构(短结构)。

在列表、散列和有序集合的长度较短或者体积较⼩的时候,Redis可以选择使⽤⼀种名为压缩列表(ziplist)的紧凑存储⽅式来存储这些结构。压缩列表是列表、散列和有序集合这3种不同类型的对象的⼀种⾮结构化(unstructured)表⽰:与Redis在通常情况下使⽤双链表表⽰列表、使⽤散列表表⽰散列、使⽤散列表加上跳跃表(skiplist)表⽰有序集合的做法不同,压缩列表会以序列化的⽅式存储数据,这些序列化数据每次被读取的时候都要进⾏解码,每次被写⼊的时候也要进⾏局部的重新编码,并且可能需要对内存⾥⾯的数据进⾏移动。

  1. 压缩列表
    列表是由双向链表构成,链表包含的每个值都会由⼀个节点(node)表⽰,每个节点都会带有指向链表中前⼀个节点和后⼀个节点的指针,以及⼀个指向节点包含的字符串值的指针。每个节点包含的字符串值都会分为3个部分进⾏存储:第⼀部分存储的是字符串的长度,第⼆部分存储的是字符串值中剩余可⽤的字节数量,⽽最后⼀部分存储的则是以空字符结尾的字符串本⾝

    压缩列表是由节点组成的序列(sequence),每个节点都由两个长度值和⼀个字符串组成。第⼀个长度值记录的是前⼀个节点的长度,这个长度值将被⽤于对压缩列表进⾏从后向前的遍历,第⼆个长度值记录了当前节点的长度,⽽位于节点最后的则是被存储的字符串值。

  2. 集合的整数集合编码

    如果整数包含的所有成员都可以被解释为⼗进制整数,⽽这些整数又处于平台的有符号整数范围之内,并且集合成员的数量又⾜够少的话,那么Redis就会以有序整数数组的⽅式存储集合,这种存储⽅式又被称为整数集合(intset)。以有序数组的⽅式存储集合不仅可以降低内存消耗,还可以提升所有标准集合操作的执⾏速度。

  3. 当⼀个结构突破了⽤户为压缩列表或者整数集合设置的限制条件时,Redis就会⾃动将它转换为更为典型的底层结构类型。这样做的主要原因在于,随着紧凑结构的体积变得越来越⼤,操作这些结构的速度也会变得越来越慢。

分片结构

分⽚(sharding)是⼀种⼴为⼈知的技术,很多数据库都使⽤这种技术来扩展存储空间并提⾼⾃⼰所能处理的负载量。分⽚本质上就是基于某些简单的规则将数据划分为更⼩的部分,然后根据数据所属的部分来决定将数据发送到哪个位置上⾯。

  1. 分⽚式散列
    散列的主要⽤途就是把简单的键值对批量地存储起来。对散列进⾏分⽚⾸先需要选择⼀个⽅法来对数据进⾏划分。因为散列本⾝就存储着⼀些键,所以程序在对键进⾏划分的时候,可以把散列存储的键⽤作其中⼀个信息源,并使⽤散列函数为键计算出⼀个数字散列值。然后程序会根据需要存储的键的总数量以及每个分⽚需要存储的键数量,计算出所需的分⽚数量,并使⽤这个分⽚数量和键的散列值来决定应该把键存储到哪个分⽚⾥⾯。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 分片键计算函数
    # base 散列名字
    # key 被存储散列的键
    # total_elements 预计元素总量
    # shard_size 请求的分片数量
    def shard_key(base, key, total_elements, shard_size):
    if isinstance(key, (int, long1)) or key.isdigit():
    shard_id = int(str(key), 10) // shard_size
    else:
    shards = 2 * total_elements // shard_size
    shard_id = binascii.crc32(key) % shards
    return "%s:%s" % (base, shard_id)
  2. 分⽚集合

    1
    2
    3
    def shard_sadd(conn, base, member, total_elements, shard_size):
    shard = shard_key(base, 'x' + str(member), total_elements, shard_size)
    return conn.sadd(shard, member)
上一篇:
redis实战学习第七天
下一篇:
redis实战学习第五天