redis缓存技术
Redis简介:
概念: redis是一款高性能的NOSQL(Not Only SQL)系列的菲关系型数据库
Redis特点:
-
Redis 是一个开源的使用 ANSI、C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API。
-
Redis 通常被称为数据结构服务器,因为值(value)可以是字符串(String)、哈希(Hash)、列表(list)、集合(sets)和有序集合(sorted sets)等类型。
-
关系型数据库和非关系数据库是互补的关系,通常情况下使用关系型数据库,在适合的情况下使用NOSQL数据库能够堆关系型数据库的不足进行弥补从而提高网站的性能。
-
一般会将数据存储在关系型数据库中,在nosql数据库中备份关系型数据库的数据
目前Redis支持的键值数据类型如下:
- 字符串类型:string
- 哈希类型:hash
- 列表类型:list
- 集合类型:set
- 有序集合类型:sortedset
Redis的应用场景:
- 缓存(数据查询,短连接,新闻内容,商品内容)
- 聊天室的在线好友列表
- 任务队列(秒杀,抢购,12306抢票)
- 应用排行榜
- 网站访问统计
- 数据过期处理(可以精确到毫秒级别)
- 分布式集群架构中的session分离
安装
debian:sudo apt install redis
启动服务:执行sudo systemctl start redis
关闭服务:执行sudo systemctl stop redis
进入客户端:redis-cli
命令操作
-
字符串类型:string
1 2 3
set key value get key del key
-
哈希类型:hash
1 2 3 4
hset key field value hget key field hgetall key hdel key field
-
列表类型:list
1 2 3 4 5
lpush key value rpush key value lrange key start end lpop key rpop key
-
集合类型:set
1 2 3
sadd key value smembers key srem key value
-
有序集合类型:sortedset
1 2 3
zadd key score value zrange key start end [withscores] zrem key value
通用命令:
keys *
:查询所有的键type key
:获取键对应的value的类型del key
:删除指定的key value
持久化:
- redis是一个内存数据库,当redis服务器重启,获取电脑重启,数据会丢失,我们可以将redis内存中的数据持久化保存到硬盘的文件中。
Redis的持久化机制
-
RDB: 默认方式,不需要进行配置,默认就使用这种机制
在一定的间隔时间中,检测key的变化情况,然后持久化数据
1 2 3 4 5 6 7
编辑/etc/redis/redis.conf文件 # after 900 sec (15 min) if at least 1 key changed save 900 1 # after 300 sec (5 min) if at least 10 keys changed save 300 10 # after 60 sec if at least 10000 keys changed save 60 10000
重新启动redis服务器,并指定redis.conf:
redis-server /etc/redis/redis.conf
注意: 在linux上通过apt安装的redis,关闭服务器后重启默认会重现之前数据,也就是默认使用了RDB的方式。配置文件在
/etc/redis/redis.conf
,rdb存储文件在/var/lib/redis
目录下。 -
AOF: 日志记录的方式,可以记录每一条命令的操作。可以每一次命令操作后,持久化数据
编辑redis.windwos.conf文件
1 2 3 4 5
appendonly no(关闭aof) --> appendonly yes (开启aof) # appendfsync always : 每一次操作都进行持久化 appendfsync everysec : 每隔一秒进行一次持久化 # appendfsync no : 不进行持久化
Redis的java客户端:Jedis
使用步骤:
-
导入Jedis相关jar包
-
使用
1 2 3 4 5 6
//1. 获取连接 Jedis jedis = new Jedis("localhost",6379); //2. 操作 jedis.set("username","zhangsan"); //3. 关闭连接 jedis.close();
-
Jedis对于String,hash,list,set,linkedset的操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14
//1. 获取连接 Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口 //2. 操作 //存储 jedis.set("username","zhangsan"); //获取 String username = jedis.get("username"); System.out.println(username); //可以使用setex()方法存储可以指定过期时间的 key value jedis.setex("activecode",20,"hehe");//将activecode:hehe键值对存入redis,并且20秒后自动删除该键值对 //3. 关闭连接 jedis.close();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
//1. 获取连接 Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口 //2. 操作 // 存储hash jedis.hset("user","name","lisi"); jedis.hset("user","age","23"); jedis.hset("user","gender","female"); // 获取hash String name = jedis.hget("user", "name"); System.out.println(name); // 获取hash的所有map中的数据 Map<String, String> user = jedis.hgetAll("user"); // keyset Set<String> keySet = user.keySet(); for (String key : keySet) { //获取value String value = user.get(key); System.out.println(key + ":" + value); } //3. 关闭连接 jedis.close();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
//1. 获取连接 Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口 //2. 操作 // list 存储 jedis.lpush("mylist","a","b","c");//从左边存 jedis.rpush("mylist","a","b","c");//从右边存 // list 范围获取 List<String> mylist = jedis.lrange("mylist", 0, -1); System.out.println(mylist); // list 弹出 String element1 = jedis.lpop("mylist");//c System.out.println(element1); String element2 = jedis.rpop("mylist");//c System.out.println(element2); // list 范围获取 List<String> mylist2 = jedis.lrange("mylist", 0, -1); System.out.println(mylist2); //3. 关闭连接 jedis.close();
1 2 3 4 5 6 7 8 9 10 11 12
//1. 获取连接 Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口 //2. 操作 // set 存储 jedis.sadd("myset","java","php","c++"); // set 获取 Set<String> myset = jedis.smembers("myset"); System.out.println(myset); //3. 关闭连接 jedis.close();
1 2 3 4 5 6 7 8 9 10 11 12 13 14
//1. 获取连接 Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口 //2. 操作 // sortedset 存储 jedis.zadd("mysortedset",3,"亚瑟"); jedis.zadd("mysortedset",30,"后裔"); jedis.zadd("mysortedset",55,"孙悟空"); // sortedset 获取 Set<String> mysortedset = jedis.zrange("mysortedset", 0, -1); System.out.println(mysortedset); //3. 关闭连接 jedis.close();
-
Jedis连接池
1 2 3 4 5 6 7 8 9 10 11 12 13 14
//0.创建一个配置对象 JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(50); config.setMaxIdle(10); //1.创建Jedis连接池对象 JedisPool jedisPool = new JedisPool(config,"localhost",6379); //2.获取连接 Jedis jedis = jedisPool.getResource(); //3. 使用 jedis.set("hehe","heihei"); //4. 关闭 归还到连接池中 jedis.close();
连接池工具类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
public class JedisPoolUtils { private static JedisPool jedisPool; static{ //读取配置文件 InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties"); //创建Properties对象 Properties pro = new Properties(); //关联文件 try { pro.load(is); } catch (IOException e) { e.printStackTrace(); } //获取数据,设置到JedisPoolConfig中 JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal"))); config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle"))); //初始化JedisPool jedisPool = new JedisPool(config,pro.getProperty("host"),Integer.parseInt(pro.getProperty("port"))); } /** * 获取连接方法 */ public static Jedis getJedis(){ return jedisPool.getResource(); } }