第六章:Redis
第1节:缓存简介
1.1 什么是缓存
缓存就是数据存放在距离计算最近的位置以加快处理速度。缓存是改善软件性能的第一手段,缓存意在减少系统对数据库的过多访问,通过减少对数据库的访问次数,改用访问内存的方式,提升系统的性能。直接从内存获取数据,较之从数据库获取数据,效率可以得到显著的提升。
1.2 主流的缓存技术介绍
主流缓存技术有Redis和Memcached。二者谁的性能更高?单纯从缓存命中的角度来说,是Memcached要高,Redis和Memcache的差距不大,底层存放数据都是key/value形式存在。但是,Redis提供的功能更加的强大。 两者之间共同点: (1)都是属于 nosql系列数据库。 not only sql (2)memcached 和redis 底层都是key/value形式存放数据。 二者的区别是什么? 1、Memcache是多线程: 底层存放数据都是key/value形式: value类型:String 2、Redis是单线程 : 底层存放数据 key/value value对应的数据类型可以有多种。
1.3 redis的介绍
Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。 总结: redis key/value数据库: value 有五种数据类型。 和Memcached类似 。 支持多语言API: java c# ios php C 语言开发: vmware 公司维护 http://redis.cn/ 中文官网网站 https://redis.io/ 英文网站
第2节:安装和操作
本章主要讲解redis的下载和按装过程,在授课时要有序引导分步聚讲解按装过程。重点体现redis的服务的启动方式(前台启动和后台启动)、redis的关闭与退出、密码设置、客户端连接redis的两种方式(本地连接和远程连接)。
2.1 下载redis
打开redis官网redis.io找到Download it选择对应的版本开始下载
redis版本
2.2 linux下安装redis
下载的redis.tar.gz 是一个C语言的源码包。 通过源码编译,进行安装。
首先C语言的运行环境~
2.2.1 安装运行环境
redis是c语言开发的安装redis需要c语言的编译环境,如果没有gcc需要在线安装。 yum install gcc-c++
2.2.2 上传并解压缩
在opt目录下进行解压操作 tar -zxvf redis-5.0.9.tar.gz
2.2.3 编译
[root@localhost ujiuye]# cd redis-5.0.9 [root@localhost redis-5.0.9]# make #注意 编译动作redis目录当中进行
2.2.4 安装redis
mkdir /usr/local/ujiuye/redis #创建了一个安装目录 make install PREFIX=/usr/local/ujiuye/redis #编译安装到指定的目录。
在 /usr/local/ujiuye/redis/bin 当中 出现:
redis-benchmark
redis-check-aof
redis-check-rdb
redis-cli
redis-sentinel
redis-server
2.3 常用操作
2.3.1 启动redis服务
1. 前台启动
进入到redis的bin目录下,键入 ./redis-server 特点: 前台启动, 会把当前窗口被占用,不能进行其他的操作。 不推荐使用该方式~
2. 后台启动
从redis-5.0.5目录中找到redis.conf文件并拷贝到redis/bin目录下 cp /usr/local/ujiuye/redis-5.0.5/redis.conf /usr/local/ujiuye/redis/bin 修改redis.conf中的daemonize改为yes : 136行: daemonize yes 根据配置文件启动: ./redis-server redis.conf 启动成功: ps -ef | grep redis
2.3.2 关闭/退出
推荐使用: 客户端发出关机指令 [root@localhost bin]# ./redis-cli shutdown 暴力方式: kill -9 pid
2.3.3 设置密码(了解)
从redis-5.0.5目录中找到redis.conf文件并拷贝到redis/bin目录下 cp /usr/local/ujiuye/redis-5.0.5/redis.conf /usr/local/ujiuye/redis/bin vim redis.conf 507 行: requirepass 123456 登录: 登录成功之后后, 操作redis,必须auth进行授权~ auth 123456 总结: 一般情况, redis在使用的时候不需要设置密码。
2.3.4 redis连接
1. 本地连接
键入./redis-cli 设置了密码: auth 123456 退出客户端: exit
2. 远程连接
防火墙: systemctl stop firewalld.service 只针对当前开关机。 或者是在防火墙当中释放 6379端口号: 编辑: redis.conf 配置文件: 69 #bind 127.0.0.1 #69行注释 添加 bind 0.0.0.0 88 protected-mode no #将受保护模式设置为no 保存并且退出: 重新启动redis服务器: 然后输入 ./redis-cli -h 192.168.18.200 -p 6379 【注意】: 修改完毕配置文件, 必须重新启动redis 。
第3节:常用命令介绍【通用性指令】
本章主要介绍redis的常用指令,包括一些公共命令keys、existis、del、flushdb、flushall、type。重点介绍redis五种数据类型的中的常用命令和各种数据类型的应用场景。
3.1 keys命令
用于显示当前库中匹配的key,如果为设置为*表示显示库中所有的key 192.168.18.200:6379> keys *
3.2 exists
测试指定的key是否存在,如果存在返回1,不存在返回0。 192.168.18.200:6379> exists name (integer) 1 192.168.18.200:6379> exists address (integer) 0
3.3 del
删除库中指定的key的信息 192.168.18.200:6379> del name (integer) 1 可以一次性删除多个key的信息,同时返回被删除的个数。 192.168.18.200:6379> del name1 name2 (integer) 2
3.4 flushdb
Flushdb 命令用于清空当前数据库中的所有 key,总是返回 OK。 192.168.18.200:6379> flushdb OK
3.5 flushall
Flushall 命令用于清空整个 Redis 服务器的数据(删除所有数据库的所有 key)。 redis安装成功之后, 一共16个数据库: 0-15表示 切换数据库: select index 192.168.18.200:6379> flushall OK 注意: 企业当中禁用~
3.6 type
Type命令用于返回 key 所储存的值的类型。 192.168.18.200:6379> type name string list set 等等~
第4节:redis的数据类型
4.1 Sring类型
4.1.1 String类型介绍
string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。 string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。 string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。【了解】
4.1.2 String类型命令
1. set
设置key和value并保存到当前为中。 语法:set key value 192.168.18.200:6379> set name zhangsan OK
2. get
获取指定key的值 语法:get key 192.168.18.200:6379> get name "zhangsan" 如果指定的key 不存在, nil
3. append
在原来的值的基础上追加新值,并返回总字符串的长度。 语法:append key value 192.168.18.200:6379> append name feng (integer) 12
4. strlen
获取指定key的值的长度
语法:strlen key
192.168.18.200:6379> strlen name
(integer) 12
5. getrange
获取指定key的值,从start位置开始,end位置结束 语法:getrange key start end 192.168.18.200:6379> getrange name 2 7 "angsan"
6. setrange
从起始位置替换值 , offset 是一个偏移量 语法:setrange key offset value 192.168.18.200:6379> setrange name 2 abc (integer) 12
7. setex
设置key的值并指定存活时间 语法:setex key second value 192.168.18.200:6379> setex name2 100 lisi #当前name2只有100S存活时间 OK ttl name2 #查询剩余时间 -2:当前key已经过时。 -1:当前key 永远不过时
8. setnx
nx; not exist 先去判断当前的key是否存在,如果存在,不执行。 只有当key 不存在的时候,执行 语法:setnx key value 192.168.18.200:6379> setnx address beijing (integer) 1
9. incr
对key的值自增1 语法:incr key 192.168.18.200:6379>incr currentPage 注意: 只有数值类型可以进行自增。
10. decr
对key的值自减1 语法:decr key 192.168.18.200:6379>decr currentPage
11. incrby
对key的值递增指定步长的值 语法:incrby key number 192.168.18.200:6379>incrby currentPage 10
12. decrby
对key的值递减指定步长的值 语法:decrby key number 192.168.18.200:6379>decrby currentPage 5
13. mset
一次性设置多个key-value键值对 语法:mset key1 value1 key2 value2 .... 192.168.18.200:6379>mset name1 zhangsan name2 lisi name3 wangwu
14. mget
一次性获取多个key的值:more 语法:mget key1 key2 .... 192.168.18.200:6379>mget name1 name2
15. expire
设置key的存活时间 seconds秒数 语法:ttl key 192.168.18.200:6379>expire address 30
16. ttl
设置指定的key永久有效 语法: persist key 192.168.18.200:6379>ttl address 注意: -2 表明当前的key 失效 -1 表明当前的key 永久有效
4.2 List类型
4.2.1 List类型介绍
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边) 总结: List集合特点: 存放的元素可以重复,并且有顺序~ 有下标。 List集合类型类似于java当中的链表。 主要操作的是链表的头部和尾部
4.2.2 List类型命令
1. lpush
向key集合的左边一次添加值 语法:lpush key value1 value2.... 192.168.18.200:6379>lpush ages 22 34 21 45 20
2. rpush
向key集合的右边一次添加值 语法:rpush key value1 value2.... 192.168.18.200:6379>192.168.18.200:6379>rpush names zhangsan lisi wangwu zhaoliu zhangsan
3. lrange
取key集合中指定的start位置到stop位置的内容(-1代表集合结束) 语法:lrange key start stop 192.168.18.200:6379>lrange ages 0 2 查询前三个元素 192.168.18.200:6379>lrange ages 0 -1 查询所有 192.168.18.200:6379>lrange ages 0 -1 不查询最后一个元素
4. llen
查看key集合的长度 语法:llen key 192.168.18.200:6379>llen ages
5. lpop
删除key集合的第一个元素 语法:lpop key 192.168.18.200:6379>lpop ages
6. rpop
删除key集合的最后一个元素 语法:rpop key 192.168.18.200:6379>rpop ages
7. lindex
获取key集合的index索引的元素 语法:lindex key index lindex ages 2
8. lrem
删除key集合的count个索引的元素(集合中有重复值) 语法:lrem key count value 192.168.18.200:6379>lrem ages 2 45
4.3 Hash类型(散列)
4.3.1 Hash类型介绍
Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。 特点: key 对应的值还是一个map类型: key: value: field value1 user: {"username":"lisi","age":"21"} key : {"field1":"value1","field2":"value2"}
4.3.2 Hash类型命令
1. hset
设置key的field字段的值 语法:hset key field value 192.168.18.200:6379>hset person name lisi 192.168.18.200:6379>hset person address changsha 192.168.18.200:6379>hset person birthday 1997-10-10
2. hget
获取key的field字段的值 语法:hget key field 192.168.18.200:6379>hget person name
3. hmset
一次设置key的多个字段的值 语法:hmset key field1 value1 field2 value2 .... 192.168.18.200:6379>hmset student name wagnwu age 22 gender man
4. hmget
一次获取key的多个字段的值 语法:hmget key field1 field2 .... 192.168.18.200:6379>hmget student name age gender
5. hgetall
获取key的多个字段的值(包括键和值) 语法:hgetall key 192.168.18.200:6379>hgetall student
6. hkeys
获取key的所有字段 语法:hkeys key 192.168.18.200:6379>hkeys student
7. hvals
获取key的所有字段的值 语法:hvals key 192.168.18.200:6379>hvals student
8. hdel
删除大key小中指定的多个小key的值 语法:hdel key field1 field2 ... 192.168.18.200:6379> hdel student name gender age
9. hlen
返回key的所有键值对的个数 语法: hlen key 192.168.18.200:6379>hlen student
10. hexists
返回key的field字段是否存在 语法:hexists key field 192.168.18.200:6379>hexists student name 返回值: 1 :代表存在 0 :代表不存在
4.4 Set类型
4.4.1 Set类型介绍
Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。 Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
4.4.2 Set类型命令
set集合特点:
元素可以多个,多个元素不能重复。 set集合无序 ~
1. sadd命令
向为key的集合中添加多个值(去重) 语法:sadd key value1 value2 ... 192.168.18.200:6379>sadd empNames zhangsan lisi wangwu zhaoliu lisi
2. smembers
循环key集合中的所有值 语法:members key 192.168.18.200:6379>smembers empNames
3. scard
统计key集合中的元素个数 语法:scard key 192.168.18.200:6379> scard empNames
4. srem
删除key集合中的value值 语法:srem key value 192.168.18.200:6379>srem empNames lisi
5. spop
随机删除key集合中的某个值 语法:spop key 192.168.18.200:6379>spop empNames
6. smove
将集合中的某个值赋给另外一个集合: SMOVE 源集合 目的集合 值 语法:smove source destination member 192.168.18.200:6379>smove empNames works zhangsan
7. Sdiff
求差集 语法:Sdiff 集合1 集合2 192.168.18.200:6379>sadd seta a b c d e 192.168.18.200:6379> sadd setb c d e f g 192.168.18.200:6379>sdiff seta setb 1) "a" 2) "b" sdiff setb seta 1) "f" 2) "g"
8. sinter
求交集 语法:sinter 集合1 集合2 192.168.18.200:6379>sinter seta setb 1) "d" 2) "c" 3) "e"
9. sunion
求并集 语法:sunion 集合1 集合2 192.168.18.200:6379> sunion seta setb 1) "d" 2) "a" 3) "b" 4) "c"
4.5 sortedSet类型
4.5.1 sortedSet类型介绍
Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
4.5.2 sortedSet类型命令
sortedSet 具有set集合的特点, 又给元素添加了顺序。 【根据分数排序】
1. zadd
向为key的集合中添加多个(score-value)。 语法:zadd key score value ... 192.168.18.200:6379>zadd students 1 zhangsan 3 lisi 2 wangwu 5 zhaoliu
2. zrange
循环key的集合从start位到stop位置的值。 语法:zrange key start stop [WITHSCORES] 192.168.18.200:6379>zrange students 0 -1 1) "zhangsan" 2) "wangwu" 3) "lisi" 4) "zhaoliu"
3. zrem
删除key集合中指定的value元素。 语法:zrem key value 192.168.18.200:6379>zrem students lisi
4. zrevrange: reverse 翻转~
逆序显示key集合中的元素。 语法:zrevrange key start stop [WITHSCORES] 192.168.18.200:6379>zrevrange students 0 -1 192.168.18.200:6379>zrevrange students 0 -1 withscores
5. zrangebyscore
根据分数区间查询内容 语法:zrangebyscore key min max 192.168.18.200:6379>zrangebyscore students 2 5 withscores 带有分数查询 limit offset count offset: 偏移量 count:查询元素的个数
6. zcard
统计key集合中有多少个键值对 语法:zcard key 192.168.18.200:6379> zcard students
7. zcount
统计key集合中min到max区间元素。 语法:zcount key min max zcount students 10 50 根据与分数统计区间的元素个数。
8. zrank
统计key集合中指定元素索引。 语法:zrank students wangwu 192.168.18.200:6379>zrank students wangwu
9. zscore
统计key集合中指定元素的分数 语法:zscore key value 192.168.18.200:6379>zscore students zhangsan
第5节:java操作redis
5.1 单实例方式
5.1.1 添加依赖
jedis java redis <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>
5.1.2 创建Jedis连接对象
Jedis jedis=new Jedis("192.168.18.200",6379);
5.1.3 操作redis数据库
@Test public void testJedis() { Jedis jedis=new Jedis("192.168.18.131",6379); jedis.set("birthday", "1991-10-30"); jedis.set("address", "beijing"); String address=jedis.get("address"); String birthday=jedis.get("birthday"); System.out.println("address:"+address); System.out.println("birthday:"+birthday); jedis.close(); }
5.2 连接池方式
5.2.1 添加依赖
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>
5.2.2 构建连接池对象
//创建JedisPoolConfig对象 JedisPoolConfig poolConfig=new JedisPoolConfig(); //最大空闲连接数 poolConfig.setMaxIdle(3); //大连接数 poolConfig.setMaxTotal(5); //连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true poolConfig.setBlockWhenExhausted(true); //获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常 poolConfig.setMaxWaitMillis(30000); //在获取连接的时候检查有效性 poolConfig.setTestOnBorrow(true); JedisPool jedisPool=new JedisPool(poolConfig,"192.168.18.200",6379,30000,"123456");
5.2.3 操作redis数据库
Jedis jedis=jedisPool.getResource(); jedis.set("name", "wangxiaobing"); jedis.set("age", "22"); String name=jedis.get("name"); String age=jedis.get("age"); System.out.println("name:"+name); System.out.println("age:"+age);
5.3 操作Java对象
5.3.1 添加依赖
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.8</version> </dependency>
5.3.2 构建Person类型
public class Person implements Serializable{ private int id; private String name; private String gender; private int age; public Person() {} public Person(int id, String name, String gender, int age) { super(); this.id = id; this.name = name; this.gender = gender; this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", gender=" + gender + ", age=" + age + "]"; }
5.3.3 redis存储Person对象
一般情况下我们不会存储Java对象,因为在redis中对于对象都会把对象变成一个JSON格式的字符串,然后进行存储,这样简单明了,数据格式好,容易阅读,相比二进制数据会更小,更方便。 工具类: public class JsonUtils { // 定义jackson对象 private static final ObjectMapper MAPPER = new ObjectMapper(); /** * 将对象转换成json字符串。 * <p>Title: entityToJson</p> * <p>Description: </p> * @param data * @return */ public static String objectToJson(Object data) { try { String string = MAPPER.writeValueAsString(data); return string; } catch (JsonProcessingException e) { e.printStackTrace(); } return null; } /** * 将json结果集转化为对象 * * @param jsonData json数据 * @param clazz 对象中的object类型 * @return */ public static <T> T jsonToEntity(String jsonData, Class<T> beanType) { try { T t = MAPPER.readValue(jsonData, beanType); return t; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 将json数据转换成entity对象list * <p>Title: jsonToList</p> * <p>Description: </p> * @param jsonData * @param beanType * @return */ public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) { JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType); try { List<T> list = MAPPER.readValue(jsonData, javaType); return list; } catch (Exception e) { e.printStackTrace(); } return null; } } @Test public void testAddPerson(){ //创建JedisPoolConfig对象 JedisPoolConfig poolConfig=new JedisPoolConfig(); //最大空闲连接数 poolConfig.setMaxIdle(3); //大连接数 poolConfig.setMaxTotal(5); //连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true poolConfig.setBlockWhenExhausted(true); //获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常 poolConfig.setMaxWaitMillis(30000); //在获取连接的时候检查有效性 poolConfig.setTestOnBorrow(true); JedisPool jedisPool=new JedisPool(poolConfig,"192.168.18.200",6379,30000,"123456"); Person person=new Person(100,"张三","男",22,new Date()); Jedis jedis = jedisPool.getResource(); // jedis.set("person", JsonUtils.objectToJson(person)); jedis.hset("persons",person.getName(),JsonUtils.objectToJson(person)); jedis.close(); } @Test public void testAddPerson2(){ //创建JedisPoolConfig对象 JedisPoolConfig poolConfig=new JedisPoolConfig(); //最大空闲连接数 poolConfig.setMaxIdle(3); //大连接数 poolConfig.setMaxTotal(5); //连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true poolConfig.setBlockWhenExhausted(true); //获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常 poolConfig.setMaxWaitMillis(30000); //在获取连接的时候检查有效性 poolConfig.setTestOnBorrow(true); JedisPool jedisPool=new JedisPool(poolConfig,"192.168.18.200",6379,30000,"123456"); Jedis jedis = jedisPool.getResource(); String jsonData=jedis.get("person"); Person person=JsonUtils.jsonToEntity(jsonData,Person.class); System.out.println(person); jedis.close(); } 提供fastjson 解析器工具类: package com.offcn.utils; import com.alibaba.fastjson.JSON; public class JsonUtils { /** * 对象转换成字符串 * @param obj 任意对象 * @return String json格式的字符串 */ public static String Obj2JsonString(Object obj){ String jsonString = JSON.toJSONString(obj); return jsonString; } /** * * @param jsonString json格式字符串 * @param clz 传递类型 * @param <T> * @return 返回值T ,任意类型 */ public static <T> T JsonString2Obj(String jsonString,Class<T> clz){ T t = JSON.parseObject(jsonString, clz); return t; } }
第6节:spring整合redis
在开发中一般使用spring来管理redis,具体讲解spring整合redis的整合步聚。
6.1 整合思路分析
spring和redis的整合,其它就是把redis的实例化过程交给spring容器来实例化,现在我们创建Jedis对象是通过JedisPool获取的,而创建JedisPool就必须实体化JedisPoolConfig对象,所以我们把JedisPoolConfig、JedisPool都交给spring容管理,我们只从容器取获取JedisPool对象进行注入即可。
6.2 添加依赖
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.5.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <!-- 返回json字符串的支持 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.8</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.2.5.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies>
6.3 配置spring整合redis
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <!-- 最大空闲连接数 --> <property name="maxIdle" value="3" /> <!-- 最大连接数 --> <property name="maxTotal" value="5" /> <!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true --> <property name="blockWhenExhausted" value="true" /> <!-- 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1 --> <property name="maxWaitMillis" value="30000" /> <!-- 在获取连接的时候检查有效性 --> <property name="testOnBorrow" value="true" /> </bean> <bean id="jedisPool" class="redis.clients.jedis.JedisPool" destroy-method="close"> <constructor-arg name="poolConfig" ref="jedisPoolConfig"></constructor-arg> <constructor-arg name="host" value="192.168.18.131" /> <constructor-arg name="port" value="6379" /> <constructor-arg name="timeout" value="30000" /> <constructor-arg name="password" value="123456"></constructor-arg> </bean>
6.4 编写测试代码
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class JedisTest { @Autowired private JedisPool jedisPool; @Test public void testAddPerson(){ Person person=new Person(100,"张三","男",22,new Date()); Jedis jedis = jedisPool.getResource(); // jedis.set("person", JsonUtils.objectToJson(person)); jedis.hset("persons",person.getName(),JsonUtils.objectToJson(person)); jedis.close(); } @Test public void testAddPerson2(){ Jedis jedis = jedisPool.getResource(); String jsonData=jedis.get("person"); Person person=JsonUtils.jsonToEntity(jsonData,Person.class); System.out.println(person); jedis.close(); } }
redis: 重要~ redis 基础~
底层原理: 过期key 删除策略 , key 淘汰策略
集群: 哨兵
基础好的自行扩展~
6.5 redis 的持久化
redis: 内存当中存放~
持久化(序列化): redis将内存当中的数据持久化到外部的文件。
反序列化: 将外部文件的二进制数据 读取到内存 :
redis持久化方式:
rdb: 默认方式~ 无需配置, 默认开启~
原理: 底层是基于快照 , 生成一个dump.rdb 文件
rdb方式的优点和弊端:
优点: rdb文件的备份和恢复简单
性能最大化
rdb对于灾难性恢复比较好的选择:
弊端: 部分数据的丢失
aof:
原理: 通过记录日志文件的形式。 set name lisi 记录到日志文件
优点: 更高的数据安全性,即数据持久性 文件过大,rewrite机制重写
特点: aof默认不支持, 如果需要使用 进行配置。 redis.confg aof
弊端: aof 效率不如rdb, aof的日志文件过大。
实际生产: rdb + aof 两个模式混合使用~ 取优点~