Redis介绍

  • Redis是一种基于键值对的NoSQL数据库,与很多键值对数据库不同,redis中的值可以有string,hash,list,set,zset,geo等多种数据结构和算法组成.
  • 因为Redis会将所有的数据都放在内存中,所以他的读写性能非常惊人.
  • 不仅如此,Redis还可以将内存中的数据利用快照和日志的形式保存到硬盘上
  • Redis还提供了键过期,发布订阅,事务,流水线等附加功能.

Redis重要特性

  1. 速度快
  • Redis所有的数据都存放在内存中
  • Redis使用C语言实现
  • Redis使用单线程架构
  1. 基于键值对的数据结构服务器
  • 五种数据结构:字符串,哈希,列表,集合,有序集合
  1. 丰富的功能
  • 提供了键过期功能,可以实现缓存
  • 提供了发布订阅功能,可以实现消息系统
  • 提供了pipeline功能,客户端可以将一批命令一次性传到Redis,减少了网络开销
  1. 简单稳定
  • 源码很少,3.0版本以后5万行左右
  • 使用单线程模型法,是的Redis服务端处理模型变得简单
  • 不依赖操作系统的中的类库
  1. 客户端语言多
  • java,PHP,python,C,C++,Nodejs等
  1. 持久化
  • RDB和AOF
  1. 主从复制
  2. 高可用和分布式
  • 哨兵
  • 集群

Redis应用场景

  1. 缓存-键过期时间
  • 缓存session会话
  • 缓存用户信息,找不到再去mysql查,查到然后回写到redis
  1. 排行榜-列表&有序集合
  • 热度排名排行榜
  • 发布时间排行榜
  1. 计数器应用-天然支持计数器
  • 帖子浏览数
  • 视频播放次数
  • 商品浏览数
  1. 社交网络-集合
  • 踩/赞,粉丝,共同好友/喜好,推送,打标签
  1. 消息队列系统-发布订阅
  • 配合elk实现日志收集

Redis安装部署

目录规划

# redis下载目录
/data/soft/
# redis安装目录
/opt/redis_cluster/redis_{PORT}/{conf,logs,pid}
# redis数据目录
/data/redis_cluster/redis_{PORT}/redis_{PORT}.rdb
# redis运维脚本
/root/scripts/redis_shell.sh

安装命令

#编辑hosts文件
echo '10.0.0.51 db01' >> /etc/hosts
echo '10.0.0.52 db02' >> /etc/hosts
echo '10.0.0.53 db03' >> /etc/hosts

#创建目录
mkdir -p /data/soft
mkdir -p /data/redis_cluster/redis_6379
mkdir -p /opt/redis_cluster/redis_6379/{conf,pid,logs}

#获取redis安装包或上传安装到到该路径
cd /data/soft/
wget http://download.redis.io/releases/redis-3.2.9.tar.gz

#解压
tar zxf redis-3.2.9.tar.gz -C /opt/redis_cluster/

#创建软连接,并进入目录编译安装
ln -s /opt/redis_cluster/redis-3.2.9/ /opt/redis_cluster/redis
cd /opt/redis_cluster/redis
make && make install

#默认执行脚本
/opt/redis_cluster/redis/utils/install_server.sh

#自己创建配置文件
cd /opt/redis_cluster/redis_6379/conf/
cat > redis_6379.conf <<EOF
### 以守护进程模式启动
daemonize yes
### 绑定的主机地址
bind 10.0.0.51
### 监听端口
port 6379
### pid文件和log文件的保存地址
pidfile /opt/redis_cluster/redis_6379/pid/redis_6379.pid
logfile /opt/redis_cluster/redis_6379/logs/redis_6379.log
### 设置数据库的数量,默认数据库为0
databases 16
### 指定本地持久化文件的文件名,默认是dump.rdb
dbfilename redis_6379.rdb
### 本地数据库的目录
dir /data/redis_cluster/redis_6379
EOF

启动关闭服务

#启动
redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf

#关闭
redis-cli -h 10.0.0.51 shutdown

Redis基本操作命令

Redis有5种数据结构,他们是键值对中的值,对于键来说有一些通用的命令

  • 登录redis
#默认没有密码
redis-cli -h db01

全局命令

查看所有命键,可以使用\*做为通配符

  • keys * : 该命令极其危险,生产环境中禁止使用
db01:6379> set k1 v1
OK
db01:6379> keys *
1) "k1"
db01:6379> set kk1 v1
OK
db01:6379> keys k*
1) "k1"
2) "kk1"
db01:6379> keys *1
1) "k1"
2) "kk1"
db01:6379> keys kk*
1) "kk1"

查看键的总数,在计算键总数时不会遍历所有键,而是直接获取Redis内置的键总数变量

db01:6379> set k1 v1
OK
db01:6379> set kk1 v1
OK
db01:6379> Dbsize
(integer) 2

查看键的数据类型

db01:6379> type kk1
string

字符串

Redis并不是简单地key-value存储,实际上他是一个数据结构服务器,支持不同类型的值.这是最简单的Redis类型,如果你只用这种类型,Redis就像一个持久化的memcache服务器(注:memcache的数据仅保存在内存中,服务器重启后,数据将丢失.)

设置和获取字符串值

db01:6379> set kk1 v1
OK
db01:6379> set k1 v1
OK
db01:6379> get k1
"v1"

INCR将字符串值解析成整型.将其加1,最后结果保存为新的字符串

  • 类似命令:INCRBY,DECR,DECRBY
db01:6379> set k3 100
OK
db01:6379> INCR k3
(integer) 101
db01:6379> incrby k3 10
(integer) 111

一次存储或获取多个key对应的值

db01:6379> mset key3 v3 key4 v4 key5 v5
OK
db01:6379> mget key3 key4 key5
1) "v3"
2) "v4"
3) "v5"

删除键,无论值是什么数据结构类型,del命令都可以将其删除,可以删除多个,返回删除的数量

db01:6379> set k1 v1
OK
db01:6379> set kk1 v1
OK
db01:6379> DEL k1 kk1
(integer) 2
db01:6379> DEL k1 kk1
(integer) 0

检查键是否存在,如果单个键存在则返回1,不存在则返回0,查询多个返回存在的键的数量

db01:6379> set k1 v1
OK
db01:6379> set kk1 v1
OK
db01:6379> EXISTS k1
(integer) 1
db01:6379> EXISTS k2
(integer) 0
db01:6379> EXISTS k1 k2 kk1
(integer) 2
db01:6379> EXISTS k1 k1 k1
(integer) 3
db01:6379> EXISTS k1 kk1
(integer) 2

设置键过期和过期时间查询,Redis支持对键添加过期时间,当超过过期时间后,会自动删除键,重新对键复制也会修改过期时间

  • >0 : 键剩余过期时间
  • -1 : 键永不过期
  • -2 : 键不存在
db01:6379> set kk1 v1
OK
db01:6379> set k1 v1
OK
db01:6379> ttl k1
(integer) -1
db01:6379> EXPIRE k1 100
(integer) 1
db01:6379> ttl k1
(integer) 99
db01:6379> ttl k111
(integer) -2

去除超时时间

db01:6379> set k5 v5 EX 10 
OK
db01:6379> ttl k5
(integer) 8
db01:6379> persist k5
(integer) 1
db01:6379> ttl k5
(integer) -1

列表

LPUSH命令可向list的左边(头部)添加一个新元素,RPUSH命令可向list的右边(尾部)添加一个新元素,LRANGE命令可以从list中取出一定范围的元素

db01:6379> rpush list1 A
(integer) 1
db01:6379> rpush list1 A
(integer) 2
db01:6379> rpush list1 b
(integer) 3
db01:6379> rpush list1 b
(integer) 4
db01:6379> lpush list1 b
(integer) 5
db01:6379> lpush list1 c
(integer) 6
db01:6379> LRANGE list1 0 -1
1) "c"
2) "b"
3) "A"
4) "A"
5) "b"
6) "b"
db01:6379> LRANGE list1 0 -2
1) "c"
2) "b"
3) "A"
4) "A"
5) "b"
db01:6379> LRANGE list1 -2 -2
1) "b"

从list中删除元素并同时返回删除的值,可以在左边或右边操作

db01:6379> LRANGE list1 0 -1
1) "c"
2) "b"
3) "A"
4) "A"
5) "b"
6) "b"
db01:6379> lpop list1
"c"
db01:6379> lpop list1
"b"
db01:6379> rpop list1
"b"
db01:6379> rpop list1
"b"

哈希

Hash看起来就像一个hash的样子,由键值对组成,HMSET指令设置hash中的多个域,HGET取回单个域,HMGET取回一系列的值,HGETALL取回所有值

db01:6379> HMSET hk1 name zs age 13
OK
db01:6379> hget hk1 name
"zs"
db01:6379> hmget hk1 name age
1) "zs"
2) "13"
db01:6379> HGETALL hk1
1) "name"
2) "zs"
3) "age"
4) "13"

集合

集合是字符串的无序排列,SADD命令把新的元素添加到set中

#和list类型不同,set集合不允许出现重复的元素
db01:6379> sadd sk1 1 2 3
(integer) 3
db01:6379> sadd sk1 1 4
(integer) 1
db01:6379> smembers sk1
1) "1"
2) "2"
3) "3"
4) "4"
db01:6379> sadd sk2 3 4 5 6
(integer) 4
db01:6379> smembers sk2
1) "3"
2) "4"
3) "5"
4) "6"
#Srem用来删除指定的值
db01:6379> SREM sk2 3
(integer) 1
db01:6379> smembers sk2
1) "4"
2) "5"
3) "6"
db01:6379> smembers sk1
1) "1"
2) "2"
3) "3"
4) "4"
db01:6379> smembers sk2
1) "4"
2) "5"
3) "6"
#Sdiff计算集合的差集
db01:6379> SDIFF sk1 sk2
1) "1"
2) "2"
3) "3"
#Sinter计算集合的交集
db01:6379> SINTER sk1 sk2
1) "4"
#Sunion计算集合并集
db01:6379> SUNION sk1 sk2
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"

Redis持久化

RDB持久化

可以在指定的时间间隔内生成数据集的 时间点快照(point-in-time snapshot).

  • 优点:速度快,适合于用做全量备份,主从复制也是基于RDB持久化功能实现的
  • 缺点:会有数据丢失,属于重量级操作,执行频繁成本过高
  • save : save会阻塞当前redis服务器,直到RDB过程完成为止,对于内存比较大的实例会造成长时间阻塞,不建议使用
  • bgsave : redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束.阻塞只发生在fork阶段,一般时间很短.

bgsave.png

手动持久化操作

db01:6379> bgsave
Background saving started
db01:6379> 
[root@db01 conf]# ll /data/redis_cluster/redis_6379/
总用量 148
-rw-r--r-- 1 root root 148042 5月  22 16:13 redis_6379.rdb

持久化以后,杀死redis进程,再次启动redis会读取该文件

db01:6379> dbsize
(integer) 10013
db01:6379> 
[root@db01 conf]# pkill redis
[root@db01 conf]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf
[root@db01 conf]# redis-cli -h db01
db01:6379> dbsize
(integer) 10013

官方配置文件RDB持久化部分

################################ SNAPSHOTTING  ################################
#
# Save the DB on disk:
#
#   save <seconds> <changes>
#
#   Will save the DB if both the given number of seconds and the given
#   number of write operations against the DB occurred.
#
#   In the example below the behaviour will be to save:
#   after 900 sec (15 min) if at least 1 key changed
#   after 300 sec (5 min) if at least 10 keys changed
#   after 60 sec if at least 10000 keys changed
#
#   Note: you can disable saving completely by commenting out all "save" lines.
#
#   It is also possible to remove all the previously configured save
#   points by adding a save directive with a single empty string argument
#   like in the following example:
#
#   save ""

修改本地配置文件,重启生效

vi /opt/redis_cluster/redis_6379/conf/redis_6379.conf

### 以守护进程模式启动
daemonize yes
### 绑定的主机地址
bind 10.0.0.51
### 监听端口
port 6379
### pid文件和log文件的保存地址
pidfile /opt/redis_cluster/redis_6379/pid/redis_6379.pid
logfile /opt/redis_cluster/redis_6379/logs/redis_6379.log
### 设置数据库的数量,默认数据库为0
databases 16
### 指定本地持久化文件的文件名,默认是dump.rdb
# 900秒内如果有1个key发生变动就保存,以下2个以此类推
save 900 1
save 300 10
save 60 10000
dbfilename redis_6379.rdb
### 本地数据库的目录
dir /data/redis_cluster/redis_6379

#停止
redis-cli -h db01 shutdown
#启动
redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf
  • pkill,kill杀死redis进程会执行redis的bgsaveshutdown命令,所以这2个命令会让数据持久化,但是kill -9杀死redis进程会强制退出,不会执行命令,所以不会持久化存储内存中的数据

AOF持久化

以独立日志的方式记录每次写命令,重启时再执行AOF文件中的命令,达到恢复数据的目的.AOF的主要作用是解决了数据持久化的实时性.目前已经是redis持久化的主流方式

  • 当RDB和AOF同时存在时,AOF优先被读取

aof.png

AOF持久化配置,重启生效

vi /opt/redis_cluster/redis_6379/conf/redis_6379.conf

### 以守护进程模式启动
daemonize yes
### 绑定的主机地址
bind 10.0.0.51
### 监听端口
port 6379
### pid文件和log文件的保存地址
pidfile /opt/redis_cluster/redis_6379/pid/redis_6379.pid
logfile /opt/redis_cluster/redis_6379/logs/redis_6379.log
### 设置数据库的数量,默认数据库为0
databases 16
### 指定本地持久化文件的文件名,默认是dump.rdb
# 900秒内如果有1个key发生变动就保存,以下2个以此类推
save 900 1
save 300 10
save 60 10000
dbfilename redis_6379.rdb
### 本地数据库的目录
dir /data/redis_cluster/redis_6379
#是否打开aof日志功能
appendonly yes
#每1个命令,都立即同步到aof
appendfsync always
#每秒写1次
appendfsync everysec
#写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入到aof
appendfsync no
#aof文件
appendfilename "appendonly.aof"

#停止
redis-cli -h db01 shutdown
#启动
redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf