Redis集中一个成员占用的字节数
How many bytes occupied by a member in Redis Set
我使用Redis作为内存中的哈希集。在我将1M个8字节的密钥(二进制)插入一个Set后,我发现Redis USED_MEMORY大约达到100M,这意味着单个成员需要100个字节?为什么?
或者如何配置Redis以节省内存使用。
首先,您应该始终详细说明此类问题的设置,因为内存布局取决于操作系统、内存分配器、平台和Redis版本。
在带有Redis 2.4的64位Linux盒子上,一个1M项目的8字节密钥集可以消耗87MB。
与键的大小相比,这似乎很大,但任何支持有效访问其项的动态数据结构都会带来开销。你的物品越小,开销就越大。
使用Redis,可以使用单独的链接哈希表来实现大型集合。每个条目由以下结构表示:
typedef struct dictEntry {
void *key;
void *val;
struct dictEntry *next;
} dictEntry;
因为内存分配器(jemalloc)不支持24字节类,所以使用了32字节。在这个结构中,val被设置为NULL(这是一个集合),关键点指向如下定义的对象:
typedef struct redisObject {
unsigned type:4;
unsigned storage:2; /* REDIS_VM_MEMORY or REDIS_VM_SWAPPING */
unsigned encoding:4;
unsigned lru:22; /* lru time (relative to server.lruclock) */
int refcount;
void *ptr;
} robj;
这种结构只占用16个字节。它指向关键数据本身,由这种可变长度结构表示:
struct sdshdr {
int len;
int free;
char buf[];
};
密钥为8个字节,加上一个nul字符,因此每个密钥的大小为17个字节。下一个分配类是32字节的jemalloc,所以这个结构需要32字节。
总而言之,每个项目的成本为:32+16+32=80字节。他们中有100多人。为哈希表本身添加一些空间(包含至少1M个指向dictEntry结构的指针),您会得到一个非常接近我们在这个平台上可以测量到的87MB的结果。
优化大型集合的内存占用并不是一件小事。Redis在集合较小(默认小于512项)并且键实际上是整数时执行优化。点击此处查看更多信息。
一种可能的优化是增加set max-intset entries参数,并将集合拆分为多个部分。例如,可以对项目键进行散列,以将项目分布在不同的集合上。您有myset:0、myset:1、myset:2。。。myset。要检查给定项是否为集合,则在键上计算哈希值以找到正确的myset:X条目,然后检查该特定条目。目的是将所有这些集合的大小保持在set max intset entries参数以下,以从内存优化中受益。当然,这会使在集合上完成的所有操作更加复杂,因此这实际上是复杂性和内存占用之间的权衡。
如果不知道集合中每个成员的底层结构,就不可能说出来。但是,如果存储键/值,则每个成员都存储键和值(即使值为空,它仍然需要为其保留一个引用)。
对于键的快速查找,底层结构很可能是一棵树,这意味着它需要为每个成员存储一个左指针和一个右指针(或红/黑),指向树中的左节点和右节点。在64位系统中,这些指针各为8个字节。
为了有效地分配和解除分配键/值对,每个成员节点可以具有指示其大小和可用性(已分配、已删除)的数据成员,以便可以从内存池中分配每个成员节点,并将其垃圾收集或标记为已删除和重用。典型的池分配会在每次填充前一个池时使池大小加倍,以最大限度地减少堆争用,这对多线程应用程序的性能非常重要。您使用的100M内存可能包含50M未使用(但已分配)的密钥持有者。
为什么要节省内存使用量?您是否计划存储数十亿个哈希密钥?
- 具有结构成员char数组的sscanf
- 如何将字节数组元素替换为修改的十六进制 ASCII 符号?
- 基于字节数组生成静态范围整数值
- 将字节数组转换为带有字节序问题的指针
- 使用 stbi_write_png,如何将 0 和 1 的矩形字节数组转换为单色 png 文件?
- 字节数组初始化会导致 DirectX 崩溃
- 使用 swig 追加到字节数组
- C++ 替换字节数组中项的顺序
- QDataStream 读取和写入的字节数比 QFile::length() 报告要多
- 如何从保存在 Java 中C++的字节数组中读取数字?
- 如何在C++(Arduino)中将浮点数组转换为字节数组
- 将字节数组转换为多维数组
- 为什么 sizeof 在 C++ 中给出不正确的字节数?
- 如何将带有空字符的字节数组馈送到 std::iostream 中?
- C++字节数组到整数
- 将字符串转换为无符号字符数组/字节数组
- 用于 progmem 的C++和头文件压缩的 Web 文件字节数组
- mmap 中的长度是字节数还是页数?
- Redis集中一个成员占用的字节数
- 类成员在数组中的距离(以字节为单位)