Redis使用手册
一、 简介
简单来说,Redis是一个高性能的Key-Value存储数据库。Value的值可以是字符串(String)、哈希(Hash)、列表(List)、集合(Sets)、有序集合(SortedSets)。Redis是一种典型的NoSQL非关系型数据库,在数据操作方面非常快,每秒可执行大约110000次的设置(SET)操作,每秒可执行81000次的读取(GET)操作。Redis数据存放在内存里,所以速度快,但是也受到内存空间的限制。所以要合理的利用有限的内存,将读(写)频繁的热数据放在Redis中才能更好感受到它带来的性能提升。
二、 效率对比
1. Redis与直连数据库对比
针对一个长字符串,redis和mysql处理速度如下:
读取 | 10000次 |
MySQL | 31.65s |
Redis | 1.16s |
2.Redis与本地缓存对比
1.本地缓存随着JVM的销毁而结束,Redis支持持久化,项目重启后数据仍然存在;
2.Redis可以处理每秒百万级的并发;
3.Redis有丰富的特性,如过期机制,支持丰富的存储类型,API等;
4.数据存到Redis中,多个项目间可以共享数据,本地缓存无法跨项目使用。
三、 安装
Windows下安装,启动
1、下载地址:https://github.com/MSOpenTech/redis/releases;
Redis支持 32位和64位。根据系统平台实际情况选择,选择版本下载到盘符(本文以F盘为例),解压后,将文件夹重命名为redis。
2、cmd打开命令提示框,切换至redis文件夹下,执行redis-service.exeredis.windows-service.conf(第一个参数为exe执行文件,第二个为配置文件)。
注意:这种启动方式会加载自行修改后的配置文件,直接双击redis-server.exe启动时加载默认的配置文件,自行修改的配置文件不生效。
启动后,Redis会自动监控端口数据。启动后的效果如下:
Linux下安装,启动
1. 下载并安装(本文以2.8.17版本为例)
$ wgethttp://download.redis.io/releases/redis-2.8.17.tar.gz
$ tar xzf redis-2.8.17.tar.gz
$ cd redis-2.8.17
$ make
make完后redis-2.8.17目录下会出现编译后的redis服务程序redis-server,还有用于测试的客户端程序redis-cli。
启动redis服务:$./redis-server redis.conf
四、 配置文件说明
Redis的配置文件redis.windows-service.conf位于Redis文件夹下。配置文件可以为服务配置绑定的主机、监听的端口和服务自动关闭时间等。部分说明:
1)Timeout :当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能。
2)save <seconds><changes>:指定在多长时间内,有多少次更新操作,就讲数据同步到数据文件,可以多个条件配合。例:save 900 1 表示900秒内有1个更新就将数据同步到数据文件。
3)dbfilename dump.rdb:指定本地数据库文件名。
4)dir ./:指定本地数据库存放目录。
5)rdbcompression yes: 存储至本地数据库时是否压缩数据。
6)Maxmemory:指定Redis最大内存限制,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,仍达到最大内存设置,将无法进行写操作,仍可读取数据。
7)bind:绑定的主机地址,默认本地。如果部署在远程服务器上需要将此参数注释掉。即通过远程连接时,只有redis服务中绑定了此客户端的IP,这个客户端才可以连接上。
8)protected-mode:安全保护模式。远程连接时开启安全保护模式,连接不上。远程连接需要设置为no。
9)requirepass:设置安全密码。也是一种加安全认证的方法。默认不设置密码。
更多参数配置请参考:http://www.redis.net.cn/tutorial/3504.html
五、 Java使用Redis
Redis支持五种数据类型:String、hash、list、Set、zset。在Java中使用Redis时,需要在CLASSPATH中包含Java redis驱动包。
Redis 官方网站API:http://www.redis.net.cn/tutorial/3508.html
下面对各种数据类型进行详解:
1、String
String是Redis最基本的数据类型,一个键最大能存储512MB。
Redis存储String类型的数据,即value为“String”类型。
其他String相关命令:
2、Hash
Redis Hash是一个String类型的键值对映射表,适合于存储对象类型。
Value值的形式为:Map<String,String>。
Map中键值存在则覆盖修改对应的value值,键值不存在则新增。
应用场景:
我们经常把一些结构化的信息打包长HashMap,在客户端序列化后存储为一个字符串的值,比如用户的昵称、年龄、性别、积分等,这时在需要修改其中某一项时,通常需要将所有值取出反序列化后,修改某一项的值,再序列化存储回去。这样不仅增大了开销,也不能适应并发操作的场合(两个并发的操作都需要修改积分)。而Redis的Hash结构可以使你像在数据库中Update一个属性一样只修改某一项属性值。Redis的Hash实际是内部存储的Value为一个HashMap,并提供了直接存取这个Map成员的接口:例如Key仍然是用户ID,value是一个Map,这个Map的key是成员的属性名,value是属性值,这样对数据的修改和存取都可以直接通过其内部Map的key(Redis里称内部Map的key为field),也就是通过key(用户ID)+field(属性标签)就可以直接操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题。
其他相关命令方法:
3、List
Redis list 是简单的String列表,按照插入的顺序排序。
应用场景:
使用List结构,我们可以轻松地实现最新消息排行等功能。List的另一个应用就是消息队列,可以利用List的PUSH操作,将任务存在List中,然后工作线程再用POP操作(删除并返回数组的最后一个元素)将任务取出进行执行。Redis还提供了操作List中某一段的api,可以直接查询,删除List中某一段元素。
其他相关命令方法:
4、Set
Redis Set 是String类型的无序集合。集合成员唯一,不允许出现重复的数据。
应用场景
Redis Set 提供了判断某个成员是否在一个Set集合内的接口。Sets 集合的概念就是一堆不重复值的组合。利用Redis提供的Sets数据结构,可以存储一些集合性的数据,比如在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操作,可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。
其他相关命令方法:
5、ZSet
ZSet与Set相同,也是String类型元素的集合,且不允许出现重复成员。不同的是每个元素会关联一个double类型的分数,通过这个分数对集合中的元素从小到大排序。有序集合的成员是唯一的,但是分数是可以重复的。
应用场景:
Redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sortedset可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。当你需要一个有序的并且不重复的集合列表,那么可以选择sorted set数据结构,比如twitter 的public timeline可以以发表时间作为score来存储,这样获取时就是自动按时间排好序的。
另外还可以用Sorted Sets来做带权重的队列,比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择按score的倒序来获取工作任务。让重要的任务优先执行。
其他相关命令方法:
6、事务
redis中的事务并不像mysql中那么完美,只是简单的保证了原子性。redis中提供了四个命令来实现事务,MULTI:类似于mysql中的BEGIN;EXEC:类似于COMMIT;DISCARD类似于ROLLBACK;WATCH则是用于来实现mysql中类似锁的功能。Redis事务允许在一次单独的步骤中执行一组命令,并且可以保证如下两个事项:
Redis会将一个事务中的所有命令序列化,然后按顺序执行。Redis不可能在一个Redis事务的执行过程中插入执行另一个客户端发出的请求。这样便能保证Redis将这些命令作为一个单独的隔离操作执行。在一个Redis事务中,Redis要么执行其中的所有命令,要么什么都不执行。因此,Redis事务能够保证原子性。EXEC命令会触发执行事务中的所有命令。因此,当某个客户端正在执行一次事务时,如果它在调用MULTI命令之前就从Redis服务端断开连接,那么就不会执行事务中的任何操作;相反,如果它在调用EXEC命令之后才从Redis服务端断开连接,那么就会执行事务中的所有操作。具体示例如下:
几点注意事项:
1)入队命令语法错误,此时还没有执行exec命令
虽然redis在碰到exec命令之前不会执行事务中的命令,但是,它会对每个命令进行适当的检查,当发现有某些明显的语法错误时,如参数个数不正确,则会在入队时,返回错误信息,并当看到exec命令调用discard命令进行回滚。
2) 当exec执行完毕后,执行其它命令时发生错误
当redis在执行命令时,如果出现了错误,那么redis不会终止其它命令的执行。即只要是正确的命令,无论在错误命令之前还是之后,都会顺利执行。
redis没有实现真正的回滚是因为redis只是一个key-value缓存数据库,如果加上日志回滚,将会影响其效率。
六、 持久化与数据恢复
Redis提供了两种数据持久化的方式,分别是RDB和AOF。
RDB:
默认情况下60秒刷新到磁盘一次(参数配置中可以配置),Redis的数据集保存在叫dump.rdb一个二进制文件,这种策略被称为快照,体积小,它恢复时是将快照文件直接读到内存里。Redis会单独创建一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化的数据可能丢失。
恢复方式:将rdb文件拷贝至Redis安装目录,重新启动Redis服务。
AOF:
以日志的形式记录每个写操作(读操作不记录),将Redis执行过的所有写指令记录下来,只许追加文件不可以改文件,redis启动之初会读取该文件重新构建数据。
当redis服务器挂掉时,重启时将按照以下优先级恢复数据到内存:
如果只配置AOF,重启时加载AOF文件恢复数据;
如果同时 配置了RBD和AOF,启动是只加载AOF文件恢复数据;
如果只配置RBD,启动是将加载dump文件恢复数据。
七、 WEB应用案例
缓存的对象:对一些变动不频繁,访问频繁的一些数据进行redis缓存。
在Spring中集成Redis
i. 添加项目依赖
在pom.xml文件中添加如下两个依赖包,编译时会自动从maven仓库中下载依赖。
<!--redis 缓存-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.8.4.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
ii. Redis客户端操作工具类
客户端工具类集合了对redis的参数配置,初始化连接,资源释放以及jedis对各种数据类型数据的存储,查询,删除等操作。
iii. 字典应用示例
利用redis-key先去redis中查询是否存在此数据,存在数据直接返回不继续查询数据库。在redis中查询不到数据时,向数据库中查询相应数据,随后存入redis中,返回响应数据。后续再次查询相同数据时直接从redis中获取返回。
封装字典查询类,提供两种查询方式。
使用方法:
Ø 从后台业务逻辑中调用:
① 传入dictType,获取当前Type下所有的字典对象集合;
1. 引用并声明,如下:
import org.loushang.util.RedisCachUtil;
2. 调用方式:
RedisCachUtil.getItemsByDict(String DICT_NAME);
传值说明:
DICT_NAME:字典类型。
调用示例:
RedisCachUtil.getItemsByDict (“sex”);
3. 返回值:
返回list数组,例如:
[{ITEM_CODE=1,ITEM_VALUE=男。。。},{ ITEM_CODE =2, ITEM_VALUE =女},{ ITEM_CODE =9, ITEM_VALUE=未知}]
②传入DICT_NAME和ITEM_CODE,获取具体ITEM_CODE对应的字典对象;
1.引用并声明,如下:
import org.loushang.util.RedisCachUtil;
2.调用方式:
RedisCachUtil.getItems(String DICT_NAME,String ITEM_CODE);
传值说明:
DICT_NAME:字典类型。
ITEM_CODE:字典Code值。
调用示例:
RedisCachUtil.getItems (“sex”,”1”);
3.返回值:
返回字典对象,例如:
{ DICT_Code=1, DICT_NAME =男,………..}
Ø 代码示例:
八、 参考资料
1.官方网站:http://www.redis.net.cn/tutorial/3501.html
2.http://baijiahao.baidu.com/s?id=1579764889124071897&wfr=spider&for=pc
3. https://www.cnblogs.com/lizhenghn/p/5322887.html
4.redis在Java web项目中的应用:
https://www.cnblogs.com/zhaozy/p/6265793.html
5.Redis应用场景介绍:http://www.scienjus.com/redis-use-case/
6.Redis应用场景:cnblogs.com/svan/p/5048770.html
7.Redis持久化:https://blog.csdn.net/u010648555/article/details/73433717/
https://blog.csdn.net/u010648555/article/details/73442336
http://www.redis.cn/topics/persistence.html