一.什么是Redis?
Redis(Remote Dictionary Server ),即远程字典服务.Redis是用C语言开发的一个开源的高性能键值对(key--value) 数据库. Redis是将数据存放到内存中,由于内容存取速度快所以redis被广泛应用在互联网项目中。
Redis是一种Nosql数据库: NoSQL(Not-Only SQL),泛指非关系型的数据库(关系型数据库:以二维表形式存储数据).
优点:存取速度快,官方称读取速度会达到30万次每秒,写速度在10万次每秒最有,具体限制于硬件.
缺点:对持久化支持不够良好,所以redis一般配合传统的关系型数据库使用。
Redis的应用场景:
1) 缓存(数据查询)。(最多使用)
2) 分布式集群架构中的session分离。
3) 任务队列。(秒杀、抢购、12306等等)
4) 网站访问统计。
5) 聊天室的在线好友列表。
二.Redis多数据库模式.
- 一个Redis实例开源包含多个数据库, 客户端开源指定连接某个Redis实例的哪个数据库, 就好比MySQL中创建多个数据库, 客户端连接时可以指定连接哪个数据库.
- 一个Redis实例最多可提供16个数据库, 下标从0 到 15 , 客户端默认连接的是第0号数据库, 也可以通过select选择连接哪个数据库.
选择数据的命令: select 数据库名称(0 --15).
注意:
1.redis不支持修改数据库的名称,只能通过select 0、select 1...选择数据库。
2.flushall : 清空所有数据库的所有数据.
3.flushdb: 清空当前所在数据库的数据.
三.Redis的基本命令.
- set和get:使用set和get可以向redis设置数据、获取数据.
- keys *:查看当前库中所有的key值.
- exists key:判断key值是否存在.
- expire key 过期时间(秒) : expire设置key的过期时间.
- ttl key : ttl查看key的有效期.
- clear:可以使用clear命令对redis-cli终端屏幕清屏。
- rename key new_key: 重命名key
- type key : 获取key值的数据类型
四.Redis的五种数据类型.
1.string类型:key--value
- 赋值:set key value
- 取值:get key
- 删除:del key
- 自增: incr key
- 自减: decr key
-
取值时同时对key进行赋值操作:getset key value
-
增加指定的整数: incrby key 增加的数值
-
减少指定的整数 : decrby key 减少的数值
-
向尾部追加值: append key value
-
获取字符串长度: strlen key
- 同时设置多个键值: mset k1 v1 k2 v2 k3 v3
- 同时获取多个键值: mget k1 k3
2.数据类型--hash
hash叫散列类型,它提供了字段和字段值的映射。字段值只能是字符串类型,不支持散列类型、集合类型等其它类型。
- 赋值: hset key field value
- 一次设置多个字段值: hmset key field value [field value ...]
- 取值: hget key field
- 一次获取多个字段值: hmget key field [field ...]
- 获取所有的key和value的值: hgetall key
- 删除一个或多个字段,返回值是被删除的字段个数: hdel key field [field ...]
- 增加数字: hincrby key field 增加的数字
- 判断字段是否存在: hexists key field
-
当字段不存在时赋值,类似HSET,区别在于如果字段已经存在,该命令不执行任何操作: hsetnx key field value
-
只获取字段名: hkeys key
-
只获取字段值: hvals key
-
获取字段数量: hlen key
3.数据类型--list 有顺序可重复
- 介绍: 列表类型内部是使用双向链表(double linked list)实现的,所以向列表两端添加或获取元素速度就很快。这意味着即使是一个有几千万个元素的列表,获取头部或尾部的10条记录也是极快的。
向列表左边增加元素: lpush key value [value ...]
向列表右边增加元素: rpush key value [value ...]
查看列表: lrange key start stop (获取列表中的某一片段,将返回start、stop之间的所有元素(包含两端的元素),索引从0开始。索引可以是负数,如:“-1”代表最后边的一个元素。)
从列表左边弹出元素: lpop key
从列表右边弹出元素: rpop key
获取列表中元素的个数: llen key
删除列表中指定的值: lrem key count value
-
LREM命令会删除列表中前count个值为value的元素,返回实际删除的元素个数。根据count值的不同,该命令的执行方式会有所不同:
- 当count>0时, LREM会从列表左边开始删除。
- 当count<0时,LREM会从列表后边开始删除。
- 当count=0时,LREM删除所有值为value的元素。
4.数据类型--set
在集合(set)中的每个元素都是不同的,且没有顺序。
增加元素: sadd key member [member ...]
删除元素: srem key member [member ...]
获取集合中的所有元素: smembers key
判断元素是否在集合中: sismember key member
集合差集的运算: 属于A并且不属于B的元素构成的集合。
sdiff key key : sdiff setA setB
集合交集的运算: 属于A且属于B的元素构成的集合。
sinter key key: sinter setA setB
集合的并集运算: 属于A或者属于B的元素构成的集合.
sunion key key : sunion setA setB
5.数据类型--sorted set (zset) : 有顺序,不能重复
增加元素: zadd key score member [score member ...]
获取元素的分数: zscore key member
删除元素: zrem key member [member ...]
获得排名在某个范围的元素列表: zrange key start stop [withscores]
五.持久化
Redis的高性能是由于其将所有数据都存储在了内存中,为了使Redis在重启之后仍能保证数据不丢失,需要将数据从内存中同步到硬盘中,这一过程就是持久化。
Redis支持两种方式的持久化,一种是RDB方式,一种是AOF方式。可以单独使用其中一种或将二者结合用。
1.RDB持久化
RDB方式的持久化是通过快照(snapshotting)完成的, 当符合一定条件时Redis会自动将内存中的数据进行快照并持久化到硬盘.
RDB是Redis默认采用的持久化方式,在redis.conf配置文件中默认有此下配置:
save 900 1 #900秒内容如果超过1个key被修改,则发起快照保存
save 300 10 #300秒内容如超过10个key被修改,则发起快照保存
save 60 10000 #表示60秒内如果超过10000个key被修改,则发起快照保存
在redis.conf中:
配置dir指定rdb快照文件的位置.
配置dbfilename指定rdb快照文件的名称.
Redis启动后会读取RDB快照文件,将数据从硬盘载入到内存。
-
总结:
-
优点: 让Redis的数据存取速度变快.
-
缺点: 服务器断电时会丢失部分数据(数据的完整性得不到保证).
2.AOF持久化
默认情况下Redis没有开启AOF(appendonly file)方式的持久化, 可以通过appendonly参数开启:
appendonly yes
AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的,默认的文件名是appendonly.aof,可以通过appendfilename参数修改:
appendfilename appendonly.aof
AOF持久化策略如下:
#appendfsync always #每次有数据修改发生时都会写入AOF文件。
appendfsync everysec #每秒钟同步一次,该策略为AOF的默认策略。
#appendfsync no #从不同步。高效但是数据不会被持久化。
总结:
优点: 持久性良好,能保证数据的完成性.
缺点: 大大降低了Redis系统的存取速度.
六.RedisTemplate的基本使用
学习RedisTemplate之前需要先学习一下Spring Data Redis. 在学习Spring Data Redis之前需要先了解一下Spring Data.
1.Spring Data介绍
Spring Data是Spring的一个子项目,是一个用于简化数据库访问的开源框架。而不拘泥于是关系型数据库还是NoSQL 数据存储。其主要目标是使得对数据的访问变得方便快捷,包含多个子项目:
-
Spring Data JDBC- 对JDBC的Spring Data存储库支持。
-
Spring Data JPA - 对JPA的Spring Data存储库支持。
-
Spring Data MongoDB - 对MongoDB的基于Spring对象文档的存储库支持。
-
Spring Data Redis - 从Spring应用程序轻松配置和访问Redis。
... ...
2.Spring Data Redis介绍
Spring Data Redis 是属于 Spring Data 下的一个模块,作用就是简化对于 redis 的操作。
提供了对不同 Redis 客户端的整合(Lettuce 和 Jedis),默认是 Lettuce
提供了 RedisTemplate 统一 API 来操作 Redis
支持 Redis 的发布订阅模型
支持 Redis 哨兵和 Redis 集群
支持基于 Lettuce 的响应式编程
支持基于 JDK、JSON、字符串、Spring 对象的数据序列化及反序列化
支持基于 Redis 的 JDKCollection 实现
Spring-Data-Redis针对jedis提供了如下功能:
1.提供了一个高度封装的“RedisTemplate”类,里面封装了对于Redis的五种数据结构的各种操作,包括:
2.SpringBoot2.x后RedisTemplate采用是lettuce(基于netty采用异步非阻塞式lO)进行通信,大并发下比jedis效率更高。
为什么RedisTemplate从Jedis替换为了Lettuce?
因为 jedis是同步的实现,lettuce是异步的实现。理论上大并发下应该lettuce 效率更高。
3.RedisTemplate模板使用序列化器操作redis数据,预定义的序列化方案有:
序列化器 | 说明 |
---|---|
JdkSerializationRedisSerializer | POJO对象的存取场景,使用JDK本身序列化机制,将pojo类通过ObjectInputstream/ObjectOutputstream进行序列化操作, 最终redis-server中将存储字节序列。是目前最常用的序列化策略。 |
StringRedisSerializer | Key或者value为字符串的场景,根据指定的charset对数据的字节序列编码成string,是"new String(bytes,charset)"和“string.getBytes(charset)"的直接封装。是最轻量级和高效的策略。 |
GenericJackson2JsonRedisSerializer | jackson-json工具提供了javabean与json之间的转换能力,可以将pojo实例序列化成json格式存储在redis中,也可以将json格式的数据转换成pojo实例。 |
注意: 一般我们使用StringRedisSerializer作为key值的序列化器, 使用GenericJackson2JsonRedisSerializer作为value值的序列化器.
区别是:
使用GenericJackson2JsonRedisSerializer将pojo序列化为json到Redis中时不乱码,并且所占的空间大小比较小.
使用JdkSerializationRedisSerializer将pojo序列化为json到Redis中时乱码,所占空间比较大
①.在使用时需要引入Spring Data Redis的依赖.
<!-- Spring Data Redis的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
②.在application.yml中配置Redis的地址和连接池
spring:
redis:
cluster:
nodes:
- 192.168.204.131:7001
- 192.168.204.131:7002
- 192.168.204.131:7003
- 192.168.204.131:7004
- 192.168.204.131:7005
- 192.168.204.131:7006
jedis:
pool:
max-active: 20 #连接池最大连接数
max-idle: 10 #连接池中的最大空闲连接
min-idle: 5 # 连接池中的最小空闲连接
注意: 我们在使用时一般将RedisTemplate封装为一个RedisClient工具类,对外暴露出和操作Redis原始数据类型相同的API.这样方便我们使用.
七:Redis主从复制
1.什么是主从复制?
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。 前者称为主节点(master),后者称为从节点(slave); 数据的复制是单向的,只能由主节点到从节点。 默认情况下,每台Redis服务器都是主节点,且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。
2.为什么要用主从复制?
持久化保证了即使redis服务重启也会丢失数据,因为redis服务重启后会将硬盘上持久化的数据恢复到内存中,但是当redis服务器的硬盘损坏了可能会导致数据丢失,如果通过redis的主从复制机制就可以避免这种单点故障.
3.主从配置.
1.主Redis配置. (无需特殊配置)
2.从Redis配置
修改从redis服务器上的redis.conf文件,添加slaveof 主redis ip 主redis port.
上边的配置说明当前该从redis服务器所对应的主redis是192.168.83.133,端口是6379
4.主从复制过程.
复制过程说明:
1、slave 服务启动,slave 会建立和master 的连接,发送sync 命令。
2、master启动一个后台进程将数据库快照保存到RDB文件中。
3、master 就发送RDB文件给slave。
4、slave 将文件保存到磁盘上,然后加载到内存恢复。
5、master把缓存的命令转发给slave。
注意: 主死了, 从只能读.
八.Redis集群.
1.什么是集群?
Redis 集群实现了对Redis的水平扩容,即启动N个redis节点,将整个数据库分布存储在这N个节点中,每个节点存储总数据的1/N。
Redis-cluster架构图.
redis集群为什么是6台?
(1)所有的redis节点彼此互联(PING-PONG机制),节点的fail是通过集群中超过半数的节点检测失效时才生效.
所以Redis集群最少需要3台Redis,才能保证集群中投票容错超过半数. 但是为了保证Redis集群的高可用, 就需要每台Redis有一个从节点,所以搭建Redis集群至少需要6台Redis.
为什么有一个节点挂了整个集群都挂了?
(2)存取数据时连接任一节点都可以,但集群中有一个节点fail整个集群都会fail.
Redis 集群中内置了 16384 个哈希槽,当需要在Redis 集群中放置一个 key-value 时,redis 先对 key 使用 CRC16 算法(CRC16(key) % 16384)算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点. 如果集群中一个节点死了,那么平均分配在集群中的16384个哈希槽就不完整了,无法进行数据的存储.所以整个集群都会死掉.
2.集群的搭建
1、安装ruby环境
yum install ruby
yum install rubygems
cd /usr/upload
gem install redis-3.0.0.gem
cd redis-3.0.0/src
ll *.rb
2、拷贝6台redis,并启动
1)必须删除dump.rdb和appendonly.aof文件
2)拷贝6个节点
cp -r /usr/local/redis /usr/local/redis-cluster/redis-7001
... ...
3)修改配置文件
port 7001
cluster-enable yes
... ...
4)创建启动脚本(v-y-p)
cd /usr/local/redis-cluster/redis-7001/bin
./redis-server redis.conf
cd /usr/local/redis-cluster/redis-7002/bin
./redis-server redis.conf
cd /usr/local/redis-cluster/redis-7003/bin
./redis-server redis.conf
cd /usr/local/redis-cluster/redis-7004/bin
./redis-server redis.conf
cd /usr/local/redis-cluster/redis-7005/bin
./redis-server redis.conf
cd /usr/local/redis-cluster/redis-7006/bin
./redis-server redis.conf3、使用ruby脚本搭建redis集群
cd /usr/upload/redis.3.0.0/src
./redis-trib.rb create --replicas 1 192.168.116.134:7001 192.168.116.134:7002 192.168.116.134:7003 192.168.116.134:7004 192.168.116.134:7005 192.168.116.134:7006
4、测试
./redis-cli -c -p 7001