一、认识redis
1.1、什么是redis
redis是一个高性能的、开源的、用C语言写的NoSql(非关系型数据库),严格上说不是一种数据库,是一种数据结构化存储方法的集合
redis是 以键值对(key-value)的形式存储,提供了很多方法来存储各种数据结构的数据,比如:string,hash,list,set及zset(sorted set)。
1.2、为什么要学习redis
- 数据是保存在内存,存取速度快,并发能力强
- 单线程,利用redis队列技术并将访问变为串行访问,消除了传统数据库串行控制
- 支持丰富的数据类型:如 String、List、Set、Sorted Set、Hash等
- redis相比于memcached,key/value存储丰富,在部分场合可以对关系数据库(如MySQL)起到很好的补充作用。
- redis提供了Java,C/C++,C#,PHP,JavaScript等客户端,使用很方便。
- Redis支持集群(主从同步)。数据可以主服务器向任意数量从的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。
- 支持持久化,可以将数据保存在硬盘的文件中
- 支持订阅/发布(subscribe/publish)功能
1.3、Mysql、Memcached和Redis的比较
- Memcached是将数据存储到内存中,而Redis可以将数据存储到内存或磁盘中,都是非关系型数据库(NoSql),Mysql是关系型数据库,是将数据存储在磁盘中
- Memcached和Redis都支持存储过期,mysql不支持
- Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储;
- 虚拟内存–Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘;
- 过期策略–memcache在set时就指定,例如set key1 0 0 8,即永不过期。Redis可以通过例如expire 设定,例如expire name 10;
- 分布式–设定memcache集群,利用magent做一主多从;redis可以做一主多从。都可以一主一从;
- 存储数据安全–memcache挂掉后(比如断电),数据没了;redis可以定期保存到磁盘(持久化);
- 灾难恢复–memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复;
- Redis支持数据的备份,即master-slave模式的数据备份;
- 应用场景不一样:Redis出来作为NoSQL数据库使用外,还能用做消息队列、排行榜、消息订阅、数据堆栈和数据缓存等;Memcached适合于缓存SQL语句、数据集、用户临时性数据、延迟查询数据和session等。
- 读写性能,mysql低,redis和memcache都非常高
1.4 常见使用场景
- 缓存
把经常要查询,不经常修改的数据放到内存中,那么下次读取数直接从缓存中取,可以减少下次读取数据的时间,减轻数据库的压力
- 计数器应用
网站通常需要统计访问量,浏览次数等等,比如起点网站的阅读量、微博转发、博客点赞次数等等
- 实时攻防系统
举个例子:比如 春运,有些刷票软件恶意刷票,不断尝试刷票,redis可以记录访问次数,当到达一定次数后,自动锁定IP,30分钟后解锁
- 排行榜
Redis 基于内存,可以非常快速高效的处理增加和减少的操作,相比于使用 SQL 请求的处理方式,性能的提升是非常巨大的。
Redis 的有序集合可以轻松实现“从一个大型列表中取得排名最高的N个元素”,毫秒级,而且非常简单。
- 设定有效期
设定一个数据,到一定的时间失效。 自动解锁,会员过期等等
- 自动去重应用
Uniq 操作,获取某段时间所有数据排重值 这个使用 Redis 的 set 数据结构最合适了,只需要不断地将数据往 set 中扔就行了,set 意为 集合,所以会自动排重。
- 队列
构建队列系统 使用 list 可以构建队列系统,使用 sorted set 甚至可以构建有优先级的队列系统。
秒杀:可以把名额放到内存队列(redis),内存就能处理高并发访问。限流
- 消息订阅系统
Pub/Sub 构建实时消息系统 Redis 的 Pub/Sub 系统可以构建实时的消息系统,比如很多用 Pub/Sub 构建的实时聊天系统 的例子。
二、安装Redis服务端
- Redis 的官方下载站是 http://redis.io/download, 直接下载最新版
- 配置介绍
2.1 启动服务端
-
如果需要设置密码,可以到redis.conf配置文件中设置密码
-
创建.bat文件,设置在启动服务端的时候启用密码
内容为:redis-server redis.conf
-
启动redis服务,直接双击打开设置好的.bat文件
-
连接到redis进行操作
cmd>{%redis%}/redis-cli -h ip地址 -p 端口号
ip 默认为本地 -p 默认6379
redis-cli -h ip地址 -p 6379
cmd>{%redis%}/redis-cli
2.2、使用 redis-cli 客户端基本操作
可以去下载redis命令文档:Redis_命令参考文档.chm
也可以在线阅读 www.RedisDoc.com
- 首先输入密码(如果有的话)
auth 你的密码
2.2.1、对value为String类型的常用操作命令
- set key value
将字符串值value关联到key
- get key
返回key关联的字符串值
- mset 一个或多个key-value
同时设置一个或多个 key-value
- mget 一个或多个key
返回所有(一个或多个)给定 key 的值
- incr key
将 key 中储存的数字值增1(key不存在,则初始化为0,再加1)
- decr key
将 key 中储存的数字值减1(key不存在,则初始化为0,再减1)
- incrBy key num
自增多少
- decrBy key num
自减多少
- Setex key seconds value
同时设置key的过期时间和值
2.2.2、对key的常用操作
- keys *
获取所有key列表
- del key
删除key
- expire key xx
设置key的过期时间(xx秒后过期)
- ttl key
查看key的过期时间
- flushall
清空整个redis服务器数据,所有的数据库全部清空
- flushdb
清除当前库,redis中默认有16个数据库,名称分别为0,1,2.。。15(可以用select index 命令来切换数据库)
2.2.3、对list集合的常用操作
list集合可以看成是一个左右排列的队列(列表)
- lpush key value
将一个或多个值 value 插入到列表 key 的表头(最左边)
- rpush key value
将一个或多个值 value 插入到列表 key 的表尾(最右边)
- lpop key
移除并返回列表 key 的头(最左边)元素。
- rpop key
移除并返回列表 key 的尾(最右边)元素。
- lrange key start stop
返回列表 key 中指定区间内的元素,查询所有的stop为-1即可
- lrem key count value
根据count值移除列表key中与参数 value 相等的元素count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。count = 0 : 移除表中所有与 value 相等的值。
- lindex key index
返回列表 key 中,下标为 index 的元素
- ltrim key start stop
对一个列表进行修剪,保留start和stop范围内的值
2.2.4、对set集合的常用操作
set集合是一个无序的不含重复值的队列
- sadd key member
将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略
- srem key member
移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略
- smembers key
返回集合 key 中的所有成员。
2.2.5、对SortedSet(有序集合)的操作
2.2.6、对hash类型的常用操作
- hset key name value
添加一个name=>value键值对到key这个hash类型
- hget key name
获取hash类型的name键对应的值
- hmset key name1 key1 name2 key2
批量添加name=>value键值对到key这个hash类型
- hmget key name1 name2
批量获取hash类型的键对应的值
- hkeys
返回哈希表 key 中的所有键
- hvals
返回哈希表 key 中的所有值
- hgetall
返回哈希表 key 中,所有的键和值
2.2.7、订阅/发布
- SUBSCRIBE channel [channel …]
订阅给定的一个或多个频道的信息。
- PUBLISH channel message
将信息 message 发送到指定的频道 channel 。
新开一个客户端订阅tv频道
发布nihao!消息到tv频道
订阅tv频道的客户端可以收到nihao!消息
2.3、弱事务(TCC、消息一致性)
Redis的事务在执行exec指令时,才批量执行操作,没有回滚操作
- multi
标记一个事务块的开始。
- exec
执行所有事务块内的命令。
- discard
取消事务,放弃执行事务块内的所有命令。
三、Java操作Redis
3.1、导包
如果是maven项目,可以在官方仓库中查找
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.2</version>
</dependency>
3.2、简单操作redis
3.2.1、简单配置
@Test
public void testSet() throws Exception{
//获取连接
Jedis jedis = new Jedis("127.0.0.1");
//添加数据
jedis.set("name", "ykf");
//关闭连接
jedis.close();
}
3.2.2、连接池配置
@Test
public void testRedisPool() throws Exception {
//创建连接池配置
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
//配置
jedisPoolConfig.setMaxTotal(20);//设置繁忙时最大连接数
jedisPoolConfig.setMaxIdle(5);//设置空闲时最大连接数
jedisPoolConfig.setMaxWaitMillis(2000);//设置最大等待时间
//获取连接池
JedisPool jedisPool = new JedisPool(jedisPoolConfig, "localhost");
//获取连接
Jedis jedis = jedisPool.getResource();
//设置密码
jedis.auth("123456");
jedis.set("age", "18");
jedis.set("name", "ykf");
//获取数据
System.out.println(jedis.get("age"));
}
3.3、Jedis数据结构操作
3.3.1、对key的操作
/**
* key操作:
* exists:判断key是否存在
* set:设置key的值
* get:获取key的值
* keys:获取多个key的值
* del:删除key
* expire:设置key的生存时间
* ttl:获取key的剩余生存时间
* @throws Exception
*/
3.3.2、对String的操作
/**
* String操作:
* set:添加、修改
* get:获取
* append:追加
* del:删除
*/
3.3.3、List操作
/**
* List操作:
* lpush:设置列表值
* lrange:获取list值,end为-1
* lrem:删除
* lset:修改
* sort排序:
* 数字,不用sortingParams
* 字母需要加,并且是指assii值排序
* @throws Exception
*/
3.3.4、Set操作
/**
* sadd:添加成员
* srem:删除
* smember:查看所有成员
* sinter:交集
* sinterstore:交集保存到新的set
* sunion:并集
* sunionstore:并集保存到新的set
* sdiff:差集
* sdiffstore:差集保存到新的set
*/
3.3.5、Hash操作
/**
* Hash:操作
* hset:设置或修改
* hgetAll:获取所有
* hdel:删除
* hincrBy:自增
* hkeys:查询所有的key
* hvalues:查询所要的value
* @throws Exception
*/
3.3.6、事务
@Test
public void testTransaction() throws Exception{
//创建连接池配置
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
//配置
jedisPoolConfig.setMaxTotal(20);//设置繁忙时最大连接数
jedisPoolConfig.setMaxIdle(5);//设置空闲时最大连接数
jedisPoolConfig.setMaxWaitMillis(2000);//设置最大等待时间
//获取连接池
JedisPool jedisPool = new JedisPool(jedisPoolConfig,"localhost");
//获取连接
Jedis jedis = jedisPool.getResource();
//清除数据库
jedis.flushDB();
jedis.set("name", "ykf");
jedis.set("age", "18");
//获取所有key的值
System.out.println(jedis.mget("name","age"));
//开启事务
Transaction transaction = jedis.multi();
transaction.incr("name");
transaction.incr("age");
//提交事务
List<Object> exec = transaction.exec();
System.out.println(exec);
//关闭连接
jedis.close();
//摧毁连接池
jedisPool.destroy();
}
四、Redis持久化配置
Redis 提供了两种不同级别的持久化方式:RDB和AOF,可以通过修改redis.conf来进行配置.
当满足持久化条件时,会进行持久化保存,还来不及保存的数据,会以aof日志的方式保存下来。
Redis启动时,先解析日志文件(一堆命令),恢复数据。然后还要加载rdb文件(取并集)。
4.1、RDB模式
RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照,默认开启该模式.
如何关闭 rdb 模式:
save “”
#save 900 1 //至少在900秒的时间段内至少有一次改变存储同步一次
#save xxx
#save 60 10000
4.2、AOF追加模式(重要)
AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集,默认关闭该模式。
4.2.1、开启aof模式
appendonly yes //yes 开启,no 关闭
#appendfsync always //每次有新命令时执行一次fsync,就将缓冲区的数据放入aof文件
#这里我们启用 everysec
appendfsync everysec //每秒 fsync 一次
#appendfsync no //从不fsync(交给操作系统来处理,可能很久才执行一次fsync)
其它的参数请大家看redis.conf配置文件详解
五、淘汰策略
淘汰一些数据,达到redis数据量都是有效的。选择合适的淘汰策略进行淘汰.怎么淘汰
volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意(随机)选择数据淘汰
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据(不删除任意数据.默认策略,但redis还会根据引用计数器进行释放),这时如果内存不够时,会直接返回错误)
redis 确定驱逐某个键值对后,会删除这个数据并,并将这个数据变更消息发布到本地(AOF 持久化)和从机(主从连接)。
至此,博主会在redis学习二更新spring集成redis