ziplist和intset是redis的两种value格式。顾名思义,ziplist是压缩的list,intset是存放int的set。元素在里面都是被编成bytes。
ziplist的大概思路是如果存放的字符串可以被解析成int,则以int的编码保存,节省内存。编码成int时,head包含一个字节encoding,代表int的长度,分别是2bytes,4bytes,8bytes。具体的编码格式:
* |00pppppp| - 1 byte
* String value with length less than or equal to 63 bytes (6 bits).
* |01pppppp|qqqqqqqq| - 2 bytes
* String value with length less than or equal to 16383 bytes (14 bits).
* |10______|qqqqqqqq|rrrrrrrr|ssssssss|tttttttt| - 5 bytes
* String value with length greater than or equal to 16384 bytes.
* |1100____| - 1 byte
* Integer encoded as int16_t (2 bytes).
* |1101____| - 1 byte
* Integer encoded as int32_t (4 bytes).
* |1110____| - 1 byte
* Integer encoded as int64_t (8 bytes).
intset以固定的长度编码int,有3种长度,int16,int32,int64。整个set的元素都用同一种编码,不需要元素head。这样节省一个head,当put一个int时,如果set的编码不足以容纳该元素,那么需要向上提升set的长度编码。并把存在的int重新编码拓展。这样就存在一个问题,如果set的元素大小参差不齐,那么浪费的空间会较多。
对于这两种类型的详细实现,有兴趣的同学去抠下代码或g下,网上很多分析,就不写重复的东西了。
最近的空闲时间在尝试做些redis的改进,一些想法见 http://christmaslin.iteye.com/blog/1273189。实现一个ziplist的改进版zip2list,另外实现一个新的类型,uintset,在较多的场景里,都是使用uint。为uint专门优化还是值得的。
ziplist对int编码时,只是使用了encoding的4bit,另外的4bit浪费了。在zip2list,充分使用encoding的bit。具体的编码如下:
* |1100 0000|- 0 byte
* Integer 0.
* |1100 0001| - 1 byte
* +Integer encoded 1 bytes.(1~255)
* |1100 0010| - 2 byte
* +Integer encoded 2 bytes.
* |1100 0011| - 3 byte
* +Integer encoded 3 bytes.
* |1100 0100| - 4 byte
* +Integer encoded 4 bytes.
* |1100 0101| - 5 byte
* +Integer encoded 5 bytes.
* |1100 0110| - 6 byte
* +Integer encoded 6 bytes.
* |1100 0111| - 7 byte
* +Integer encoded 7 bytes.
* |1100 1000| - 8 byte
* +Integer encoded 8 bytes.
*
* |1110 0001| - 1 byte
* -Integer encoded 1 bytes.-(1-255)
* |1110 0010| - 2 byte
* -Integer encoded 2 bytes.
* |1110 0011| - 3 byte
* -Integer encoded 3 bytes.
* |1110 0100| - 4 byte
* -Integer encoded 4 bytes.
* |1110 0101| - 5 byte
* -Integer encoded 5 bytes.
* |1110 0110| - 6 byte
* -Integer encoded 6 bytes.
* |1110 0111| - 7 byte
* -Integer encoded 7 bytes.
* |1110 1000| - 8 byte
* -Integer encoded 8 bytes.
|1100 ----| ,value>= 0,|1110 ----| value 0,所有的value都编成uint,encoding已经带符号位了。 例如 value{1} 编成 [|1100 0001| 0000 0001],value{-1} 编成 [|1110 0001| 0000 0001]. 这种编码方式一个字节都不会浪费。
对于uintset里的uint,则使用可变长编码,同样不需要使用head。可变长编码,一个int64的长度是1~10bytes。可变长编码的大概思路是一个byte只使用7bit,最后1bit用来代表是否编码结束,如果0,则结束,否则为1.这个小技巧在leveldb和Tokyo Cabinet都可以见到。(题外话,leveldb的思路和实现都值得一看,通过数据的版本号来解决读写的并发,精简的mvcc。此外,还像个单机版的hbase)。这个方案避免参差的int造成的浪费。当然,它可能也需要付出额外的字节。但在大部分情况下,对内存的利用应该比定长编码更优。当然,在性能上比intset,可能会有所损耗。对set的插入,删除,读取都需要查找,为了增加查找速度,int在里面是排序的,intet和uintset都是这样。但是intset的int编码长度固定,容易定位元素,2分查找是非常方便。而uintset的uint长度未知。在二分时不是针对uint的数目二分,而是针对set编码后的一个大byte array做2分。有2点可能造成性能损失:不是准确的二分和定位到一个byte时,要向前扫描找到uint的起始byte,虽然最多扫描不超过10byte。此外,要获取指定序号的uint,只能从起点向后或终点向前扫描(视乎序号更接近起点还是终点)。
在内存紧缺的情况下,uintset还是有存在的价值的。
这两种类型已经实现,相关的想法也提到官方社区。
分享到:
相关推荐
4. **丰富的数据类型**:Redis 不仅支持基本的数据类型,还支持复杂的数据结构。 5. **主从复制**:Redis 支持主从复制,可以进行读写分离,提高性能和数据安全性。 6. **高可用性**:通过 Redis Sentinel 系统或...
Redis-sentinel是Redis的作者antirez完成的,因为Redis实例在各个大公司的应用,每个公司都需要一个Redis集群的管理工具,被迫都自己写管理工具来管理Redis集群,antirez考虑到社区的急迫需要(详情),花了几个星期写...
2. `redis-cli.exe`:Redis命令行客户端,用于与Redis服务器交互,执行命令和查看数据。 3. `redis.windows.conf`:Redis的配置文件,可以自定义服务器的各项设置。 4. `redis-benchmark.exe`:性能测试工具,可以...
1. **Redis的数据类型**: - 字符串(Strings):最基础的数据类型,可以存储文本或二进制数据。 - 哈希(Hashes):用于存储键值对集合,适合表示对象。 - 列表(Lists):有序的字符串集合,支持两端插入和弹出操作。...
Redis 6.0.8是Redis的一个稳定版本,它带来了许多新特性和改进,包括更好的性能、安全性和可扩展性。这个版本引入了多线程I/O,提高了处理大量并发连接的能力,同时保持了Redis的核心特性,如键值存储、发布/订阅、...
redis Redis 数据类型.docx 来源:https://www.runoob.com/redis/redis-data-types.html
1. 支持多种数据类型:字符串、哈希表、列表、集合和有序集合,使得Redis在多种场景下都能发挥高效作用。 2. 持久化:通过RDB(快照)和AOF(Append Only File)两种方式实现数据持久化,确保即使在服务器重启后也能...
Redis,全称Remote Dictionary Server,是一款开源的、高性能的键值对存储系统,常用于数据缓存、消息队列和数据库等场景。在Windows环境下安装和使用Redis,可以通过下载对应的二进制压缩包来实现,比如"redis-...
此外,了解 Redis 的数据类型(如字符串、哈希、列表、集合、有序集合)及其操作命令,对于高效地利用 Redis 来解决实际问题至关重要。在 Windows 环境下,使用提供的批处理脚本和可执行文件,可以轻松部署和管理 ...
- **Redis Release Notes.docx**:包含了Redis 2.8.12的发行说明,详细列出了新特性、改进和已知问题。 4. **可执行文件** - **redis-server.exe**:Redis服务器进程,负责处理客户端请求并管理数据存储。 - **...
List类型是Redis中基于链表实现的数据结构,它可以存储多个有序的元素。List类型非常适合实现消息队列,用户会话管理等场景。在C#中,我们可以使用如下代码操作List类型: ```csharp redis.LPush("message:queue", ...
首先,Redis支持多种数据类型,包括字符串(Strings)、哈希(Hashes)、列表(Lists)、集合(Sets)和有序集合(Sorted Sets)。这些数据类型不仅满足基本的键值存储需求,还能处理更复杂的数据操作,如列表的推入...
"最新版windows redis-desktop-manager-2020.5.zip"指的是2020年5月发布的Windows版本的Redis Desktop Manager,包含主要的更新和改进。 Redis是内存数据结构存储系统,常被用作数据库、缓存和消息中间件。它支持...
Redis 5.0.14是该数据库的一个稳定版本,相比于早期版本,它可能包含了一些性能优化、新功能、错误修复和改进。以下是对Redis 5.0.14在Windows环境中的使用进行的详细解析: 1. **安装**: 包内的"Redis-x64-5.0.14....
本资源提供了Redis在Windows平台上的64位版本,包括`.msi`安装包和`.zip`压缩文件。 首先,`.msi`文件是Windows Installer的安装包格式,用于在Windows操作系统上方便地安装软件。`Redis-x64-5.0.14.msi`是Redis ...
Redis是一种高性能的键值数据库,特别适用于实时数据存储和快速读写操作。在这个"Redis-x64-5.0.9.zip"压缩包中,包含了适用于Windows 64位系统的Redis安装程序,即"Redis-x64-5.0.9.msi"。这个版本的Redis是针对64...
Redis 6.2.1 现已发布,该版本升级迫切性程度为低:修复了编译问题。具体更新内容如下: Bug 修复 修复带有已删除记录的 stream 的 sanitize-dump-payload(#8568) 防止将 client-query-buffer-limit 配置设置为...
$ redis-dump $ redis-dump -u 127.0.0.1:6379 > db_full.json $ redis-dump -u 127.0.0.1:6379 -d 15 > db_db15.json $ < db_full.json redis-load $ < db_db15.json redis-load -d 15 # OR $ cat db_full | redis...
Redis是一款高性能的键值数据库,尤其适用于数据缓存和实时数据操作。在本文中,我们将深入探讨 Redis ...在使用过程中,务必注意定期备份数据,确保数据安全,同时关注 Redis 社区的更新,以便获取最新的改进和修复。