redis

redis是高级的key,value型数据库

五种数据类型
  字符串string
  散列hash
  列表lists
  集合sets
  有序集合sortedsets

redis简介

redis属于NoSql,(not only sql) 不仅仅是sql

特点:
    存储结构跟mysql不一样,采用的是key,value型存储

NoSql也还有很多种类:
    redis
    mongodb
    Hadoop
    Hbase

NoSql和SQL的区别

应用场景的不同;
存储方式不同;
NoSql支持关系相对简单的数据查询,不支持事务
sql支持关系相对复杂的数据查询,支持事务

redis的特性

redis是开源的,内存中的数据结构存储系统,他可以用作数据库、缓存和消息中间件
redis是由C语言编写的,支持数据持久化,是key-value型数据库
应用在缓存,消息队列中
redis支持数据备份,也就是master-slave模式

redis的优势

性能高,读取速度快,
    原因:redis是完全基于内存实现的,还是单线程数据库

一般用作缓存数据库,数据放到内存中
大型项目中,一般用来存储session,购物车订单

redis的安装

1.yum安装

#前提得配置好阿里云yum源,epel源
#查看是否有redis包
yum list redis
#安装redis
yum install redis -y
#安装好,启动redis
systemctl start redis

# 检查redis是否工作了
redis-cli    #redis 客户端工具
#进入交互式环境后,执行ping,返回pong表示安装成功
127.0.0.1:6379> ping
PONG

2.源码编译安装

# 编译安装的优势
1. 编译安装可以扩展第三方模块
2.编译安装可以统一路径,Linux软件约定安装在 /opt下
3.软件仓库版本一般比较低, 编译安装可以根据需求, 安装最新版本
1.下载redis源码
wget http://download.redis.io/releases/redis-4.0.10.tar.gz
2.解压缩
tar -zxvf redis-4.0.10.tar.gz
3.切换redis源码目录
cd redis-4.0.10.tar.gz
4.编译源文件
make
5.编译好后,src/目录下有编译好的redis指令
6.make install 安装到指定目录,默认在/usr/local/bin

# 可以直接make && make install

redis的可执行文件

./redis-benchmark      用于进行redis性能测试的工具
./redis-check-dump     用于修复出问题的dump.rdb文件
./redis-cli            redis的客户端
./redis-server         redis的服务端
./redis-check-aof      用于修复出问题的AOF文件
./redis-sentinel       用于集群管理

redis配置文件

redis配置文件名为   redis.conf 
# 这个文件可以自定义, 比如:
# touch redis.s18.conf 内容如下
grep -v '^$'  redis.conf |grep -v "^#"  >  redis.s18.conf   # 去掉空格和#开头的数据写到redis.s18.conf中

# 然后 vim redis.s18.conf

bind 192.168.81.132          #redis启动地址
protected-mode yes            #开启redis安全模式
port 6800                    #更改redis端口 
daemonize yes                #redis后台启动 
pidfile /var/run/redis_6379.pid
loglevel notice             # 日志等级是notice
logfile ""
requirepass  666        #设置redis的密码 redis没有账号

启动、使用redis

启动redis
# redis-server   指定加载的文件
# 如果redis-server  后面什么也不指定, 会以非daemon的方式来运行,且默认服务端口为6379。
redis-server  redis.s18.conf

使用redis
redis-cli -h 192.168.81.132 -p 6800
# 参数解释 -h 指定主机地址  -p  指定redis端口
# 登录之后通过auth指令 验证密码 如果没有密码直接ping
使用ping命令,确保redis正常可用回复了一个pong

redis简单的指令

keys  *           # 查看数据库所有的key
type  key         #查看key的类型
expipe addr 20    #给addr这个key设置20秒的过期时间
ttl key           #查看key的过期剩余时间
persist key       # 取消key的过期时间
exists key        # 判断key存在    存在返回1    否则0
del keys          # 删除key    可以删除多个
dbsize            # 计算key的数量
set key value     # 设置key value
               # set name  attila
get  key          # get name  得到的是attila

redis字符串命令(string)

getrange key start end  #返回key中子字符
setnx key value  #只有在key不存在的时候才设置key值
setlen key  #返回字符串的长度
incr key   #将key中储存的数字值增一
decr key  #将key中存储的数字减一
append key value #如果key存在,将value追加到老的value后面
mset key value [key1 value1......] #同时设置多个key-value对,仅限所有的key都不存在

redis哈希命令(hashs)

hdel key f1 [f2....]  #删除一个或多个哈希表字段
hexists key f1   #查看字段是否存在
hget  key f1  #获取指定字段值
hgetall key  #获取key中所有的字段和值
hkeys key   # 获取哈希表中所有的字段
hlen key    #获取哈希表中字段的数量
hset key f1 value #将哈希表中key中的字段设为value 

redis列表命令(list)

lindex key index  #通过索引获取列表中的元素
linsert key before/after pivot value #在列表key前/后插入元素
llen key  #获取列表长度
lpop key  #移除并获取列表中的第一个元素
rpop key  #移除列表最后一个元素,返回值为移除的元素
lrem key count value  #移除列表元素
rpush key v1 [v2....]  #在列表中添加一个或多个值

redis集合命令(set)

sadd key m1 [m2....]  #向集合中添加一个或多个成员
scard key  #获取集合中成员数
sdiff k1 [k2]  #返回给定集合中的差集
sinter k1 [k2] #返回给定集合中的交集
smembers key  #返回集合中所有的成员
somve s1 s2 m1  #将m1从s1集合中移动到s2集合中
spop key  #随机删除并返回一个元素

redis有序集合命令(sorted set)

zadd key s1 m1 [s2 m2] #向有序集合中添加一个或多个成员,或更新成员
zcard key  #获取有序集合中的成员
zcount key min max #计算指定区间的成员数
zrank key m1 #返回有序集合中成员的索引
zrem key m1 [m2] #移除有序集合中一个或多个成员

*****重头戏--->redis持久化存储

Redis是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失,为了解决这个问题,
Redis提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失。

1.RDB持久化存储

RDB(持久化)
内存数据保存到磁盘  可以定期执行, 也可以手动(save)执行
RDB持久化产生的RDB文件是一个经过压缩的二进制文件,这个文件被保存在硬盘中,redis可以通过这个文件还原数据库当时的状态。
在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)
优点:速度快,适合做备份,主从复制就是基于RDB持久化功能实现
缺点:如果持久化存储期间,redis发生故障,会发生数据丢失 rdb通过再redis中使用save命令触发 rdb
# (在redis文件下)开启rdb功能,vim redis-rdb.conf 内容如下: daemonize yes port 6379 logfile /data/6379/redis.log dir /data/6379 # 这个需要mkdir -p /data/6379 dbfilename dbmp.rdb # 当触发save之后会生成dbmp.rdb这个文件 bind 127.0.0.1 save 900 1 # 每隔900秒有一个操作就执行持久化 save 300 10 save 60 10000

开启redis服务端,支持rdb功能

redis-server redis-rdb.conf

登录redis,写入数据,手动执行save出发持久化,会生成一个二进制的数据dbmp.rdb文件

redis-cli  #登录redis

127.0.0.1:6379> set name  attila
OK
127.0.0.1:6379> save
OK

#退出redis,在进来, keys * name还在;如果不持久化,就没有数据

2.AOF持久化存储

AOF 文件中的命令全部以redis协议的格式保存,新命令追加到文件末尾。
优点:最大程度保证数据不丢失
缺点:日志记录非常大

# 在redis文件下 vim redis-aof.conf 写入如下数据: daemonize yes port 6379 logfile /data/6379/redis.log dir /data/6379 # 也需要创建/data/6379 appendonly yes appendfsync everysec

aof持久化的两个参数

appendonly yes
appendfsync  always    总是修改类的操作
             everysec   每秒做一次持久化
             no     依赖于系统自带的缓存大小机制

启动redis服务

redis-server  redis-aof.conf

检查.data/6379文件

[root@localhost 6379]# ls
appendonly.aof    redis.log

登录redis,写入数据

redis-cli  # 登录redis
127.0.0.1:6379> set name  attila
OK
127.0.0.1:6379> save
OK

# 最后退出redis, 重新登录redis, 输入keys *  检查结果name还在,表示持久化存储成功

实时检查appendonly.aof文件信息

# 再开一个窗口,然后检测实时动态
[root@localhost 6379]# tail -f appendonly.aof

redis在不重启的情况下,从rdb转化到aof

首先版本必须是redis2.2版本以上

# 1.启动rdb方式的redis

# 2.通过命令切换为aof模式,仅仅是临时生效,切换到aof,切换后还得修改配置文件
127.0.0.1:6379> CONFIG set appendonly yes   #开启AOF功能
OK
127.0.0.1:6379> CONFIG SET save ""  #关闭RDB功能
OK

3.还得修改redis的配置文件,让他下次重启也是aof
修改redis-rdb.conf  为如下配置,以后重启也是aof了
daemonize yes
port 6379
logfile /opt/6379/redis.log
dir /opt/6379
appendonly yes
appendfsync everysec

# 重启redis数据库

# 4.至此redis已经切换到 aof模式下了

redis主从同步,故障切换,集群搭建

redis主从同步

准备三个配置文件,实现一主两从的redis数据库结构(这三个配置文件仅端口不同)

# redis-6379.conf 文件, 写入下面数据:

port 6379
daemonize yes
pidfile /data/6379/redis.pid
loglevel notice
logfile "/data/6379/redis.log"
dbfilename dump.rdb
dir /data/6379
protected-mode no

下面两个6380,6381直接替换就行

sed  "s/6379/6380/g"  redis-6379.conf  >  redis-6380.conf
sed  "s/6379/6381/g"  redis-6379.conf  >  redis-6381.conf

# 把6379配置成主库,6380和6381配置成从库,  需要在6380和6381的conf文件下写入:
slaveof  127.0.0.1  6379

分别启动这三个redis数据库

redis-server redis-6379.conf
redis-server redis-6380.conf
redis-server redis-6381.conf

通过命令查看数据库的身份信息

127.0.0.1:6379> info  Replication     # 身份是master
127.0.0.1:6380> info  Replication     # 身份是slave
127.0.0.1:6381> info  Replication     # 身份是slave

然后测试:在主库中写入数据,在从库中查看,如果同步即为正常

redis故障切换

手动进行主从故障切换

# 演示:
1. 手动检查进程, 杀死主库. (6379)
2.手动切换到其中的一个从库(6380),去掉conf文件中的slave身份
3.切换到另一个从库(6381), 把conf文件中的slave指向改成 slaveof  127.0.0.1  6380

自动主从切换,应用哨兵机制

哨兵集群自动切换机制原理:
    给数据库配置几个哨兵,让他们监控着这个数据库,隔一段时间去问一下主库,看看他是否还活着,如果主库在规定的时间内没有回复哨兵消息,哨兵就认为主库已经挂了,他会告诉其他哨兵主库挂了,其他哨兵验证之后,如果发现真的挂了,哨兵会从其他的从库中选举新的主库,然后把其他的从库slaveof执行这个新的主库。

环境配置(准备三个配置文件)

# redis-6379.conf
port 6379
daemonize yes
logfile "6379.log"
dbfilename "dump-6379.rdb"
dir "/opt/redis/data/"

# 另外两个如下
sed "s/6379/6380/g" redis-6379.conf  > redis-6380.conf 
sed "s/6379/6381/g" redis-6379.conf  > redis-6381.conf 
# 然后分别在这两个文件下写上:
slaveof  127.0.0.1  6379

分别启动三个redis

redis-server redis-6379.conf 
redis-server redis-6380.conf 
redis-server redis-6381.conf 

分别查看他们的身份

redis-cli  -p  6379  info  Replication     # master 主库
redis-cli  -p  6380  info  Replication     # slave  从库
redis-cli  -p  6380  info  Replication     # slave  从库

准备三个哨兵,检测redis状态

# redis-26379.conf   写入下面数据:
port 26379  
dir /var/redis/data/
logfile "26379.log"

#  当前Sentinel节点监控 127.0.0.1:6379 这个主节点
# 2代表判断主节点失败至少需要2个Sentinel节点节点同意,少数服从多数 
# s18ms是主节点的别名
sentinel monitor s18ms 127.0.0.1 6379 2

# 每个Sentinel节点都要定期PING命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过30000毫秒30s且没有回复,则判定不可达
sentinel down-after-milliseconds s18ms 30000

# 当Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,
# 原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为1
sentinel parallel-syncs s18ms 1

# 故障转移超时时间为180000毫秒
sentinel failover-timeout s18ms 180000
daemonize yes

# 另外两个配置信息也只有端口不同

分别启动三个哨兵

[root@localhost s18msredis]# redis-sentinel redis-26379.conf 
[root@localhost s18msredis]# redis-sentinel redis-26380.conf 
[root@localhost s18msredis]# redis-sentinel redis-26381.conf

查看哨兵身份

[root@localhost s18msredis]# redis-cli -p 26379 info sentinel
[root@localhost s18msredis]# redis-cli -p 26380 info sentinel
[root@localhost s18msredis]# redis-cli -p 26381 info sentinel

测试

# 这三个哨兵检测这一主两从
1.干掉(主库)6379,查看6380和6381这两个的身份信息
2.发现其中一个从库(如:6380)变成了主库, 另一个从库变成了6380的从库   # 这个选主库是随机的.
3.当6379复活后,会自动变成6380的从库

# 原理其实就是把6380里面的slave移除啦,然后把6381的slaveof指向了6381, 6379复活后slaveof也指向了6381

redis集群搭建

redis集群搭建的原理:
    其实就是对数据进行切片分摊,就好比一个一吨重的货物让一匹马去拉肯定拉不动,但是把这一吨重的货物分摊成5份,让5匹马去拉,就可以拉动了。

redis-cluster虚拟槽分区

虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有的数据映射到一个固定范围内的整数集合,整数定义为槽(slot)。

Redis Cluster槽的范围是0 ~ 16383, 一共16384个槽位 。

槽是集群内数据管理和迁移的基本单位。采用大范围的槽的主要目的是为了方便数据的拆分和集群的扩展,

每个节点负责一定数量的槽。

 

准备节点(服务端)
服务端运输数据,分配16384个槽位,管理数据
ruby脚本自动帮你分配槽位

环境配置

# 创建redis-7000.conf  文件并写入如下数据:
port 7000
daemonize yes
dir "/opt/redis/data"
logfile "7000.log"
dbfilename "dump-7000.rdb"
cluster-enabled yes   #开启集群模式
cluster-config-file nodes-7000.conf  #集群内部的配置文件
cluster-require-full-coverage no  #redis cluster需要16384个slot都正常的时候才能对外提供服务,
                      换句话说,只要任何一个slot异常那么整个cluster不对外提供服务。 因此生产环境一般为no

# 我们一共需要6个节点,也就是需要6个配置文件,3主3从,最少6个才能保证高可用,这6个配置文件仅仅是端口不同

其他几个配置文件

sed "s/7000/7001/g" redis-7000.conf > redis-7001.conf

redis-7001.conf
redis-7002.conf
redis-7003.conf
redis-7004.conf
redis-7005.conf

分别启动6个redis数据库

[root@localhost s18cluster]# redis-server redis-7000.conf 
[root@localhost s18cluster]# redis-server redis-7001.conf 
[root@localhost s18cluster]# redis-server redis-7002.conf 
[root@localhost s18cluster]# redis-server redis-7003.conf 
[root@localhost s18cluster]# redis-server redis-7004.conf 
[root@localhost s18cluster]# redis-server redis-7005.conf

把槽分配给马车,这样马车才能运数据,ruby会自动分配

#安装准备ruby语言的环境,用于自动化创建redis集群
1.下载ruby
wget https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.1.tar.gz
2.解压缩
tar -zxvf ruby-2.3.1.tar.gz
./configure --prefix=/opt/ruby/
3.安装
make && make install

配置ruby的path,就是找到ruby的bin目录的路径,然后添加到/etc/profile中的PATH中去,通过ruby的软件包管理工具安装redis模块 (gem就是类似于python的pip工具)

wget http://rubygems.org/downloads/redis-3.3.0.gem

通过gem安装这个包

gem install -l redis-3.3.0.gem

找到ruby创建redis集群脚本工具

[root@localhost s18cluster]find /opt  -name redis-trib.rb
/opt/redis-4.0.10/src/redis-trib.rb

此时就可以通过绝对路径ruby来创建redis集群工具,进行槽位分配(开启所有集群)

/opt/redis-4.0.10/src/redis-trib.rb create --replicas 1 127.0.0.1:7000
  127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
# --replicas 1  表示每个主节点有一个从节点

查看集群状态

redis-cli -p 7000 cluster info 
redis-cli -p 7000 cluster nodes  #等同于查看nodes-7000.conf文件节点信息

集群主节点状态
redis-cli -p 7000 cluster nodes | grep master
集群从节点状态
redis-cli -p 7000 cluster nodes | grep slave

集群已经创建完毕,开始测试

redis-cli -p 7000  -c    # -c 开启集群模式
!!! 当你在其中一个节点中,创建redis的key,只要redis的key经过了重定向,分配到不同的节点中,代表集群搭建ok
     重定向之后, 只要在集群里有数据 无论在哪个port里面,都可以get出来,比如set name attila 被分配到7001  你登录7000也能get到name

redis缓存击穿,缓存穿透,缓存雪崩

redis缓存穿透

redis缓存穿透:
当我们查询的时候查询一个一定不存在的对象时,redis每次请求都会去存储层去查找,这就失去了缓存的意义,当出现很多次或有人恶意发起查询的时候,数据库就挂掉了

解决方法:
    采用布隆过滤器,即将所有可能存在的数据存储到一个bitmap中,一个一定不存在的数据会被这个bitmap拦截,避免对存储层的查询压力。

redis缓存击穿

缓存击穿:
    当一个key在即将要过期的时间时,有大量的请求对其进行发送,这些请求发现这个key过期之后,会疯狂的从后端存储库中查找数据,此时会瞬间将DB搞崩。

解决方法:
    使用互斥锁,

redis缓存雪崩

缓存雪崩:
    指的是我们设置缓存时使用了相同的过期时间,导致缓存到达某一时间同时失效,请求全部到了存储库,瞬间压力过重导致雪崩。

解决方法:
    将缓存失效时间分开,这样缓存失效率降低,防止过期时间一过而导致的集体失效的事件。
原文地址:https://www.cnblogs.com/zty1304368100/p/11191433.html