从搭建到应用,一文读懂Redis

2017-11-15 10:32 阅读 570 views 次 评论 0 条


Redis是一个基于C语言开发,开源高性能的高级内存数据库系统,其存储的是非结构化的key-value数据,而且支持多种丰富的数据类型。作为一个高效快速的内存数据存储系统,Redis在分布式系统和WEB开发中得到广泛应用。本文主要针对Redis本身做相关的介绍,包括安装启动、基本的数据结构类型、高级应用、以及其所拥有的优势和相关应用场景等。

安装启动

  • 下载版本:以版本redis-4.0.1.tar.gz为例,可以到官网下载;

  • 解压:tar -zxvf redis-4.0.1.tar.gz;

  • 编译:到解压目录下执行make进行编译;

  • 启动Redis Server:./redis-server,如下图所示,说明Redis正常工作:

  • 启动一个Redis Client./redis-cli

通过以上的步骤,完成了Redis Server的部署和启动,并通过一个客户端成功连接到Redis Server,在客户端命令行中可以输入“info”来查看Redis服务器的所有统计信息。

数据类型

Redis作为一种高级的key-value存储系统,其键值所支持的数据类型包括5种:string(字符串类型)、hash(哈希类型)、list(列表类型)、set(集合类型)、zset(sortedset有序集合类型)。

Redis内部使用一个redisObject对象来表示所有的key和value。redisObject 最主要的信息如图所示:type代表一个对象具体是何种数据类型,encoding是不同数据类型在Redis内部的存储方式,如果type=string,则代表是string类型,encoding则可能是raw或者int类型。

下面主要介绍一下5种基本数据类型:

  • string(字符串)

Redis中的字符串是一个字节序列。常用命令:set(赋值)/get(查询)/decr (自减)/incr(自增)/mget(查询多个key)等。

使用:string是最简单最常用的一种数据类型,是一个二进制安全的字节序列,最高可存储512M字节数据。

实现:string在Redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr、decr等操作时会转成数值型进行计算,此时redisObject的encoding字段为int。

  • hash(哈希类型)

Redis哈希是键值对的集合,是字符串字段和字符串值之间的映射;常用命令:hset(添加赋值)/hget(查询)/hgetall(查询所有字段和值)等。

使用:如果要存储一辆汽车的信息对象数据,其中包括汽车ID、品牌、颜色和价格,通过汽车ID希望获取该汽车的品牌或者颜色或者价格等;

实现:Redis的hash数据结构内部value的存储方式为HasMap,并提供了直接存储这个Map成员的接口。如上图所示,Redis本身的key为汽车ID,value为一个Map,Map中的key标识属性,value标识属性对应的值。

  • list(列表类型)

Redis列表是字符串的有序可重复结构。常用命令:lpush(列表头部添加元素)/rpush(列表尾部添加元素)/lpop(头部删除元素)/rpop(尾部删除元素)/lrange(查询元素)等。

使用Redis列表是字符串列表,不支持嵌套其他数据类型,可以向列表的头部或者尾部进行添加和删除操作;应用的场景非常多,比如存储文章评论列表,存储用户的粉丝列表,黑名单列表等,也可以作为重要的消息队列来使用。

实现:Redis的list数据结构的实现是一个双向链表,支持正向反向遍历查找,方便用户操作的同时,也增加了内存开销。

  • set(集合类型)

Redis集合是字符串的不重复无序结构。常用命令有sadd(添加元素)/spop(删除)/smembers(查询)/sunion(添加多个集合)等,基本示例如下所示。

使用:Redis集合是字符串集合,不支持嵌套其他数据类型;与list的功能相似,但是提供了自动去重功能,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。

实现:实现方式可以参考Java中的Set实现;内部实现是一个value永远为null的HashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因。

  • sorted set(有序集合类型)

sorted set在set基础上为每个元素都关联了一个分数score,通过score来实现排序功能。常用命令:zadd/zrange/zrem/zcard,如下图中zadd添加元素命令中的0/1/2表示该元素对应的score分数,这个分数就是用来排序的标准,而且可以修改。

使用Redis有序集合是在集合的基础上增加了排序功能,规则是按照该元素对应的Score进行排序。实际应用来讲主要是涉及到排序的功能场景都可以使用,例如实现文章按点击量排序,微博热搜榜,论坛热帖等。

实现:内部使用HasMap和跳跃表来保证数据的存储和有序,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。

以上简单地介绍了Redis支持的5种数据类型,基本上跟一些编程语言的数据结构类似,也很容易理解,后续的应用重点是在于灵活的使用,在这一方面还是需要根据不同的业务场景,选取不同的方案来解决处理。

高级应用

  • Redis发布订阅功能

发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息,主要的目是解耦消息的发布者和接收者,不仅在代码级别解耦,更是在系统架构上解耦。Redis作为一个发布订阅Server,在订阅者和发布者之间起到了消息路由的作用。

订阅者可以通过subscribe和psubscribe命令向Redis Server订阅自己感兴趣的消息类型,Redis将消息类型称为通道(channel)。当发布者通过publish命令向Redis Server发送特定类型的消息时。订阅该消息类型的全部Client都会收到此消息。这里消息的传递是多对多的。一个Client可以订阅多个channel,也可以向多个channel发送消息。

客户端a发布Iphone消息,示例:

所有订阅Iphone消息的客户端都会收到消息,示例:

  • Redis支持事务功能

Redis对事务的支持还比较简单,主要是保证同一个Client发起的事务中的命令可以连续执行,而中间不会插入另一个客户端的命令。

当一个客户端发起事务命令multi时,这个连接会进入一个事物上下文,该连接后续的命令不会立即执行,而是先放到一个队列中去,当此连接收到exec命令后,Redis才会顺序执行队列中的命令。然后将执行的所有的命令结果一同返回到客户端。

简单的事务处理如下所示:

  • Redis管道功能

Redis是一个支持请求/响应协议TCP服务器。一个请求发送到完成的步骤如下:Client发送一个查询到服务器,并从套接字中读取信息,这个过程通常是在阻塞式地等待服务器的响应,服务器处理命令并将响应返回给客户端。

Redis的管道功能指客户端在同一个请求中可以同时发送多个命令,在这个过程中无需等待每个命令的响应,而是在最后读取每个命令的响应回复。

  • Redis持久化功能

Redis是一个基于内存的数据库,但是它也是支持数据持久化的。如果业务需要,可以开启其持久化功能,将内存中的数据持久化到磁盘中去,从而保证数据的安全性和完整性。

Redis最常用的两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)。RDB方式:简单讲就是在不同的时间点,将Redis存储的数据生成快照并存储到磁盘等介质上;AOF方式:简单讲就是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序再将指令都执行一遍,从而恢复数据。通过修改Redis的相关配置文件,就可以很容易地配置使用持久化方式。

以上列举了Redis常见的几种高级应用,包括事务、持久化、管道、发布订阅等,当然Redis还有其他的一些功能,包括Redis相关的配置、排序、集群部署、主从服之间的数据复制等等,在此不再一一赘述。

应用实例

Redis支持多种客户端语言,如下图所示,其中包括常用的Java、Python、Ruby、Node.js、R、Scala等:

Java方面的客户端主要是Jedis,使用时只需要导入相应的客户端jar包即可。

相关的Github地址:https://github.com/xetorthio/jedis

相关的Maven配置:

Jedis使用举例,下面是针对于Redis的hash类型进行的一个单元测试:

总结

Redis作为一个内存数据库,其具有如下的优势:

  1. 异常快:Redis非常快,每秒可执行大约110000次的设置(SET)操作,每秒大约可执行81000次的读取/获取(GET)操作。

  2. 支持丰富的数据类型:Redis支持开发人员常用的大多数数据类型,例如列表、集合、排序集和散列等等。

  3. 操作具有原子性:单进程单线程作业,所有操作都是原子操作,这确保如果两个客户端并发访问,Redis服务器能接收更新的值。

  4. 多实用工具:是一个多实用工具,可用于多种用例,如:缓存、消息队列(Redis本地支持发布/订阅)、应用程序中的任何短期数据。例如,WEB应用程序中的会话、网页命中计数等。

总而言之,尽管Redis是一个非常棒的内存数据库,但是要充分利用其各方面的优势,还是要结合特定场景下的业务进行良好的设计,这样才能高效地为业务服务。

本文从几个方面介绍了Redis的数据类型和基本使用,希望能够对感兴趣的开发者有所帮助,有助于自己的业务实现以及优化。


版权声明:本文版权由木秀林网所有,转载请保留链接:从搭建到应用,一文读懂Redis
分类:Redis 标签:

发表评论


表情