1.Redis数据库的概念
Redis(Remote Dictionary Server)是一个由ANSI C语言编写的、开源的、遵守BSD协议、支持网络、基于内存也可持久化的日志型、提供多种语言API的键值对数据库。Redis是键值对类型的内存数据库,整个数据库加载在内存中,在内存中进行操作,定期通过异步方式把内存数据刷新(Flush)到硬盘上进行保存。Redis可保存多种数据结构,单个值的最大限制是1GB。Redis可对存入的键值对设置过期(Expire)时间;Redis通过异步的方式将数据写入磁盘,具有快速和数据持久化的特征。Redis的缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读/写,其适合的场景局限在较小数据量的高性能操作和运算上。
2.Redis数据库的数据类型
Redis数据库中的所有数据都是键值对,在底层以二进制字节数组的格式存放,客户端在使用时需要自行转换。Redis键值是二进制安全的,用任何二进制序列作为键,空字符串也是有效键。数据库完全在内存中操作数据,数据类型丰富。Redis支持丰富的数据类型,包括“5种基本”数据类型+“4种特殊”数据类型。5种基本类型即字符串(String)、哈希表(Hash Table)、列表(List)、集合(Set)、有序集合(Ordered Set),4种特殊数据类型是基数统计(HyperLogLog)、位图(BitMap)、地理位置(Geo)和流(Streams)。
1)字符串:字符串是最基本的类型,可包含任何数据如JPG图片或者序列化的对象,字符串大小最多是512MB。字符串是最常用的一种数据类型,可应用于普通的键值对存储,具有定时持久化、操作日志及复制等功能。
2)哈希表:哈希表是一个键值对集合,可以用来存储对象的属性或者其他类型的映射关系,一个字符串类型的域(Field)和值(Value)的映射表,适用于存储对象。例如,存储用户信息对象数据,用户ID为键、值是用户对象,包含姓名、性别、生日、专业等信息,哈希表内部存储的值为一个哈希映射(HashMap)。图7-5给出了用户信息的定义,第一列的键值对是具体的键,person值是一个哈希值。哈希表不支持二进制位操作,一个哈希表中最多包含2 32 -1个键值对。
图7-5 用户信息的定义
3)列表:列表是简单的字符串列表,它的实现为一个双向链表,支持正向、反向查找和遍历,可用于发送缓冲队列等功能。
4)集合:Redis中的集合是一个无序的、去重的元素集合,元素是字符串类型,最多包含2 32 -1个元素。集合是通过哈希表实现的,所以添加、删除、查找的复杂度都是 O (1)。Redis的集合对外提供与链表类似的功能,集合就是一堆不重复值的组合。集合的编码方式有两种,即整数集合和哈希表。当集合中的所有元素都是整数,并且元素的个数小于set-max-intset-entries时,使用整数集合作为集合的编码方式,所有元素都保存在整数集合里面。当集合中的所有元素不都是整数,或者元素的个数大于等于set-max-intset-entries,使用哈希表作为集合的编码方式,哈希表的每一个键都是字符串对象,每一个字符串都包含一个集合的元素,哈希表的值全部为NULL。
5)有序集合:有序集合是有序的、去重的,元素是字符串类型、每一个元素都关联着一个浮点数分值(Score)的集合,按照分值从小到大的顺序排列元素。分值可以相同,最多包含2 32 -1个元素,成员是唯一的,分值则可以重复。有序集合的使用场景与集合类似,区别是集合不是自动有序的,有序集合通过用户额外提供一个优先级的参数来为成员排序,是插入有序的(即自动排序)。有序集合在内部使用哈希映射和跳跃表(Skip List)来保证数据的存储和有序。
6)基数统计:基数表示不重复的元素,例如 A ={1, 2, 3, 4, 5}, B ={3, 5, 6, 7, 9},那么基数(不重复的元素)=1,2,4,6,7,9;允许容错,即可以接受一定误差。使用基数统计结构可以节省内存,以便统计各种计数,比如注册IP数、每日访问IP数、独立IP访客UV(Unique Visitor,指某站点被多少台计算机访问过,以用户计算机的Cookie作为统计依据,00∶00-24∶00内相同的客户端只被计算一次)、在线用户数、共同好友数等。
7)位图:BitMap数据结构操作二进制位来进行记录,只有0和1两个状态。比如统计用户信息的登录/未登录、打卡/不打卡等,具有两个值的行为状态的数据都可以使用位图。存储一年的打卡状态需要的内存是365bit/天,约46(365/8)个byte。位图是一个对位进行操作的字符串,每个位置只存储0和1的一串二进制数字,下标是其偏移量。通过一个位来表示某个元素对应的值或状态,其中的键对应元素本身,底层是通过对字符串的操作来实现的。Redis从2.2.0版本开始新增了setbit、getbit、bitcount等相关命令。
8)地理位置:Redis的GEO特性是在Redis 3.2版本中推出的,它将用户给定的地理位置信息存储起来,用来完成和空间位置相关的算法功能:两地之间的距离、某范围内的人等。在直播业务中,实现检索附近主播功能的方法是:开播时写入主播ID的经纬度,关播的时候删除主播ID元素,系统中维护一个具有位置信息的在线主播集合供线上检索。
9)流:Redis Stream是Redis 5.0版本新增加的数据类型,专门为消息队列设计。Redis Stream类用于实现支持消息的持久化、自动生成全局唯一ID、ACK(肯定应答)确认消息的模式、支持消费组模式等功能。流就是Redis实现的内存版分布式发布-订阅消息系统,支持多播的可持久化的消息队列,用于实现发布和订阅功能;Redis Stream的结构有一个消息链表,将所有加入的消息都串起来,每个消息都有一个唯一的ID和对应的内容。消息是持久化的,Redis重启后其内容还在。