首页 » PHP教程 » phpredislist批量技巧_浅谈redis的数据类型

phpredislist批量技巧_浅谈redis的数据类型

访客 2024-11-07 0

扫一扫用手机浏览

文章目录 [+]

2009年,Redis由Salvatore Sanfilippo开拓并发布在Github上。
最初,Redis是一个键值对存储系统,支持字符串类型、列表类型、凑集类型和哈希类型等数据构造。

2010年,Redis开始盛行,并成为一个盛行的数据存储和缓存办理方案。
Redis2.0发布,加入了VM I/O异步优化、持久化等新特性。

phpredislist批量技巧_浅谈redis的数据类型

2012 年,Redis 2.6发布,引入了限流限速、事务、Lua 脚本等诸多新特性。
Redis2.6变得更加稳定和安全,并且Redis2.6开始盛行作为缓存和行列步队办理方案。

phpredislist批量技巧_浅谈redis的数据类型
(图片来自网络侵删)

2014年,Redis3.0发布,支持了集群模式、多种新的数据构造、复制和分区等新功能。
Redis3.0开始得到广泛运用,特殊是在大规模互联网运用上,受到了极大的关注和支持。

2016年,Redis4.0发布,支持模块化、快照异步和集群等扩展浩瀚特性。

目前,Redis 已经成为一个成熟、盛行、高性能的键值存储系统,被广泛运用于各种web运用和企业级运用处景,目前最近的redis版本可以支持的数据类型有9种,分别是:

String

字符串(String)数据类型是Redis最基本的数据类型,用于存储一串字符,其最大长度为 512 MB。
String类型是Redis中最大略的数据类型,在Redis 中,String类型不仅仅可以存储字符串,还可以存储数字、图片、序列化后的工具等任何数据类型。

Redis中的字符串类型的底层数据构造是SDS(Simple Dynamic String),SDS是Redis所利用的字符串库,比较C措辞原生的字符串,SDS更加灵巧和高效。
以下是Redis中字符串类型的底层数据构造图:

redisStringObject {

+--------+

| type |

+--------+

| 1Byte |

+--------+

| encode|

+--------+

| 1Byte |

+--------+

| length|

+--------+

| 4Byte |

| |

| |

+--------+

| buf[] |

| |

| |

+--------+

}

个中,type 表示字符串类型,为 0x1。
encode 表示字符串编码办法,Redis中有两种编码办法:int 和 raw。
int 表示该字符串可以被阐明为整数,raw 表示是纯字符串类型。
为了节省空间,Redis 会考试测验将可以被阐明为整数的字符串存储为整数类型,从而节约空间。
length 表示字符串的长度。
buf[] 表示字符串的内容,底层利用char 数组存储。

总体来说,Redis 的字符串类型利用了一些比较底层的数据构造,例如 char 数组和整数类型,使得字符串类型更加高效和灵巧。

Hash

Hash 数据类型用于存储字段和字段值的映射,类似于关联数组或者哈希表,个中字段是字符串类型,字段值可以是 String 类型、Hash 类型或者 List 类型。

类型利用的底层数据构造是哈希表,以下是 Redis 中哈希表的底层数据构造示意图:

redisHashTable {

+--------+

| size |

+--------+

| used |

+--------+

| dict |

+--------+

}

个中,size 表示哈希表数组的大小,used表示哈希表中已利用的节点数量。

dict 表示哈希表数组,其底层数据构造是一个数组和链表。
详细来说,哈希表数组中的每个元素都指向一个链表头,而每次插入数据时,会根据key的哈希值打算出数组下标,并在对应链表中插入一个新的节点。
当哈希表冲突时,多个不同的 key 可能司帐算出相同的哈希值,此时它们会被插入到同一个链表中,这便是所谓的拉链法(open addressing with chaining)。
哈希表的优点是其插入、删除和查找操作的韶光繁芜度均为 O(1),即常数韶光,因此非常高效。
其余,哈希表还支持动态扩容和缩容,可以根据插入数据的情形自动调度大小,从而使得哈希表利用起来非常方便。

List

列表(List)数据类型是 Redis 存储有序元素的凑集,个中每个元素都包含一个字符串。
List类型支持从左边或右边进行元素的添加和删除操作。

列表类型利用的底层数据构造是双端链表,以下是Redis 中双端链表的底层数据构造示意图:

redisList {

+--------+

| head |

+--------+

| tail |

+--------+

| len |

+--------+

}

个中,head 表示双端链表的头结点,tail 表示双端链表的尾结点,len 表示双端链表的长度。

双端链表是一种分外的链表,它除了存储数据外,还同时存储了先驱节点和后继节点的地址。
这个特性使得它支持快速的尾部插入和头部插入操作,以及快速的尾部删除和头部删除操作。
在Redis中,列表类型还支持基于双端链表实现的双向循环链表,即列表尾部的下一个节点是列表头部,列表头部的前一个节点是列表尾部。
这样可以使得某些操作的繁芜度更低,例如将列表尾部的数据插入到列表头部。
其余,Redis 还供应了一种名为 quicklist 的列表存储办法,它将一个列表分成多少个小块,每个小块以压缩列表的形式存储。
这样可以有效地节省内存空间,提高查询性能,但会导致增删操作的繁芜度略有增加。

Set

凑集(Set)数据类型是 Redis 存储无序且不重复元素的凑集,每个元素都是唯一的。
Set 类型支持添加、删除和检讨元素是否存在等操作。

Set 类型利用的底层数据构造是哈希表(Hash Table),以下是Redis中哈希表的底层数据构造示意图:

redisSet {

+--------+

| dict |

+--------+

| len |

+--------+

}

个中,dict表示底层利用的哈希表,len表示凑集中元素的数量。
哈希表是一种基于数组的数据构造,它通过散列函数将数据映射到数组中的一个位置,以达到快速访问元素的目的。
Redis 中的哈希表利用链表法来办理哈希冲突问题,即当多个元素映射到同一个位置时,将这些元素放在同一个链表中,实现了高效的增、删、查操作。
Set 类型中的元素是无序、不重复的,利用哈希表来存储可以使得元素的插入、删除和查找等操作均摊韶光繁芜度为 O(1),非常高效。
同时,Redis 还供应了一些基于凑集的操作,例如求交集、并集和差集等,这些操作也可以通过哈希表来实现。

Sorted set

有序凑集(Sorted Set)是 Redis 的一个独特数据类型,类似于凑集(Set)数据类型,但是每个元素都有一个干系的分数,用于对元素进行排序。

sorted Set 类型底层利用的是两种数据构造:跳跃表(Skip List)和哈希表(Hash Table)。

以下是 Redis Sorted Set 的底层数据构造示意图:

redisSortedSet {

+--------+

| dict |

+--------+

| skiplist|

+--------+

}

个中,dict表示底层利用的哈希表,skiplist表示底层利用的跳跃表。
跳跃表是一种随机化数据构造,它在保持有序性的同时,实现了高效的查找和插入操作。
跳跃表利用多级索引的办法,以空间换韶光,大大提高了查找的效率。
在Redis 中,Sorted Set利用跳跃表来实现有序性,并且跳跃表中的每个节点都存储了获取元素的指针,以是在元素的查找上也非常高效。
哈希表是用于保存 Sorted Set 中元素名与分值之间的对应关系的。
它供应了 O(1) 繁芜度的元素插入、删除和查找操作。
哈希表在插入和删除操作上具有很高的效率。
Redis的Sorted Set 既具有字典(Hash Table)的高效性,又具有有序列表(Skip List)的快速查找、插入、删除操作的特点。
这种构造为Sorted Set 供应了强大的功能,如范围查询(按照分值的范围来查询元素)、排行榜等。

Bitmaps

是一种分外的字符串类型,其值仅包含二进制位,每个位的值只能是0 或 1。
Redis 的 Bitmaps 模块供应了一组分外的操作命令,Bitmaps 可以用于位图、计数器、邮件系统中邮件是否已读等场景。

Redis中的Bitmaps指的是位图数据构造,用于高效地存储和操作二进制位。
底层实现采取了内存位图的办法,非常适宜于存储和操作大量的二进制位信息。
下面是 Redis Bitmaps 的底层数据构造示意图:

Key: online_users

+----+--------+--------+--------+--------+--------+--------+--------+--------+

| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ...

+----+--------+--------+--------+--------+--------+--------+--------+--------+

| 00 | 010001 | 101101 | 000011 | 110000 | 011011 | 101010 | 111111 | 000000 | ...

+----+--------+--------+--------+--------+--------+--------+--------+--------+

上面的示意图是一个 Bitmaps 工具,个中每一位存储了一个二进制数值(0 或 1),可以表示某个元素的存在与否等信息。
在 Redis 中,位图数据构造可以通过 SETBIT、GETBIT 等命令进行位的存取,还可以通过 BITOP 等命令进行位运算,包括 AND、OR、XOR 等操作。

在实际运用中,Redis 位图数据构造常用于统计在线用户、标记用户行为等场景,通过对二进制位的操作来快速、高效地完成干系任务。
由于位图数据构造在底层采取了内存位图的形式,因此非常紧凑,可以高效地处理大量的二进制位信息,而且操作效率很高,是一种非常精良的存储和操作二进制信息的数据构造。

Hyperloglog

Redis 中的 HyperLogLog 是一种基数统打算法,用于高效地统计凑集中的元素数目。
HyperLogLog 可以在 O(1) 的韶光繁芜度内完成对不同元素数量的估算,而且空间利用率非常低。
HyperLogLog 利用的事理非常大略,它将每个元素映射到一个哈希值上,并对哈希值进行操作,以得到元素的数量估算值。
HyperLogLog 中利用的算法基于 PFCM 或 Linear Counting 算法,它可以通过打算位图中前导 0 位数的均匀值来估算元素数量,从而有效地降落内存空间利用率。

Redis 中的 HyperLogLog 数据构造用于实现基数统计,底层采取稀疏精度优化法 (Sparse Precision Optimization),可以用很小的内存空间对高基数(cardinality)做近似计数。
HyperLogLog 的基本思想是保存一些随机 hash 值的最大前导零的数量,根据这个数量近似打算基数。

下面是 HyperLogLog 底层数据构造实现示意图:

Key: counter

+-------+----------------------+

| Index | Value |

+-------+----------------------+

| 0 | 0001001 |

| 1 | 0010000 |

| 2 | 0000010 |

| 3 | 0000101 |

| ... | ... |

| N-1 | 1001010 - (max(29, 0))|

+-------+----------------------+

上面的示意图是一个 HyperLogLog 的计数器,个中以二进制位存储 hash 值的最大前导零数量,即 leading zero count (LZC)。
每个 LZC 都存储在一个单独的索引位置上,可以通过索引位置来进行快速计数和合并操作。
在 Redis 中,HyperLogLog 的底层实现采取了稀疏精度优化法,只会记录 LZC 不为 0 的 hash 值,这样可以大大节省内存空间,并且不会对计数结果产生过大的偏差。
HyperLogLog 的精度紧张由内部的 LZC 位数和插入的 hash 值数量决定。
通过调度这两个成分,我们可以得到不同精度的计数结果。
HyperLogLog 的基数统计偏差一样平常在 1% 以内,纵然是千万级别的基数也可以利用不到 1 KB 的内存来进行计数。

Geo

Redis中供应了Geo数据类型,用于处理地理空间坐标信息。
Geo数据类型支持将坐标点和对应的名称存储在 Redis 的有序凑集中,同时供应了一些基于地理位置的功能,如打算两个地理位置之间的间隔、查找某个地理位置的附近的位置等。
通过利用Geo数据类型,用户可以更方便地处理基于地理位置的业务场景,如舆图运用中的位置查找、城市做事中的附近店铺搜索、出租车做事中的车辆调度等。

Redis中的GEO数据类型是用来存储地理位置信息的数据类型,它基于 zset 实现。
在zset中,每个成员都会带有一个称为score的分值来进行有序排序,而 GEO 数据类型中,分值就表示成员的经度或纬度,成员则是一个地点的名称。
Redis采取zset来存储地理位置信息,底层利用了Ziplist和Skiplist。

下面是 GEO 底层数据构造实现示意图:

Key: city

+-------+----------+-----------+

| Score | Longitude| Latitude |

+-------+----------+-----------+

| 29.0 | 112.0 | 34.0 |

| 31.0 | 130.0 | 45.0 |

| 37.0 | 23.0 | 53.0 |

| 41.0 | 125.5 | 39.5 |

| 45.0 | -79.0 | 43.5 |

+-------+----------+-----------+

上图中展示了一个名为city的GEO数据类型,它包含了五个地点的经纬度信息。
个中每个地点由一个分值和两个数据项组成,分值是经度或纬度信息,经度和纬度则是地点的位置。
对付GEO数据类型,用户可以通过经度、纬度和半径的组合快速地查找周围其他地点。
通过zset的score和member,我们可以直接对 GEO 数据类型进行排序和范围查询操作。

Stream

Redis Stream是Redis5.0版本新增的数据类型,用于支持行列步队等场景。
Redis Stream类似于Kafka的模型,可以支持可靠的传输和多个消费者的并行消费等功能。

Redis Stream 的底层实现采取了类似跳表(Skip List)的数据构造,每个 Stream 对应一个长度可变的双向链表,每个对应链表中的一个节点。
跳表的每一层都是一个由多少节点组成的双向链表,每个节点包含了下一层的起始节点指针等信息,可以快速地进行查找和插入操作,同时也担保了数据的有序性。

Redis Stream 的数据构造示意图如下:

Stream N(名字)

+- Message 1

| +-------- Key1: Value1

| | +---- Key2: Value2

| | | + Timestamp

| | | |

| | | v

| v v v

+- Message 2 ---+

| +-------- Key1: Value1

| +---- Key2: Value2

| + Timestamp

|

v

在上面的数据构造示意图中,Stream N 表示一个 Stream 的名称,每个 Message 代表一个,Key-Value 表示中的数据,Timestamp 表示的韶光戳。
在实际的运用中,用户可以向 Stream 中添加、读取消息、删除等,通过利用 Stream 数据类型可以方便地实现行列步队等功能。

标签:

相关文章

phpajax代码技巧_PHPAJAX 与 MySQL

AJAX 数据库实例下面的实例将演示网页如何通过 AJAX 从数据库读取信息:本教程利用到的 Websites 表 SQL 文件:...

PHP教程 2024-12-08 阅读0 评论0