Redis 基础实践
Redis 基础实践
简介
非关系型数据库,数据存储在内存中的, key-value形式,主要作为缓存服务器和消息队列。
特性
- 高数读写,数据类型丰富。 10万级别/s
- 支持持久化,多种内存分配及回收策略
- 支持弱事务,消息队列,消息订阅
- 支持高可用,支持分布式分片集群
企业缓存数据库解决方案对比
优点 | 缺点 | |
---|---|---|
Memcached | 高性能读写,数据单一类型,支持客户端分布式集群,一致hash多核结构,多线程,读写性能高 | 无持久化,节点故障可能出现缓存穿透,分布式需要客户端实现,跨机房数据同步困难,架构扩容复杂度高 |
Reids | 高性能读写,多数据类型支持,数据持久化,高可用结构,支持定义虚拟内存,支持分布式分片集群,单线程读写性能高 | 多线程读写较Memcached慢 |
Tair | 高性能读写,支持三种存储引擎(ddb\rdb\ldb),支持高可用,支持分布式集群,支撑了淘宝业务的缓存 | 单机情况下,读写性能低于其他两个 |
redis应用场景
- 数据高速缓存,web会话缓存 (session cache)
- 应用榜应用
- 消息队列,发布订阅
- 数据使用频率高,比较重要(数据持久化)。
安装
yum -y install gcc
cd /local
wget http://download.redis.io/releases/redis-5.0.7.tar.gz
tar -zxvf redis-5.0.7.tar.gz -C /local
mv redis-5.0.7 redis
cd /local/redis
make PREFIX=/local/apps/redis install
echo 'PATH=/local/apps/redis/bin:$PATH' > /etc/profile.d/redis.sh
. /etc/profile.d/redis.sh
tree /local/apps/redis/
mkdir /local/apps/redis/{etc,logs,data,run}
cp /local/redis/redis.conf /local/apps/redis/etc/
#前台启动
redis-server /local/apps/redis/etc/redis.conf
处理Waing 修改配置参数
重启os,编辑服务并设置开机自启动
useradd -r -s /sbin/nologin redis
chown redis.redis /local/apps/redis/ -R
#编辑redis服务启动文件
vim /usr/lib/systemd/system/redis.service
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/local/apps/redis/bin/redis-server /local/apps/redis/etc/redis.conf --supervised systemd
ExecStop=/bin/kill -s QUIT $MAINPID
LimitNOFILE=64000
Type=notify
[Install]
WantedBy=multi-user.target
chmod +x /usr/lib/systemd/system/redis.service
chkconfig redis on
waring 处理
609:M 12 Mar 2022 08:17:47.238 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
#backlog参数控制的是三次握手的时候server端收到client ack确认号之后的队列值,即全连接队列
vim /etc/sysctl.conf
net.core.somaxconn = 1024
vm.overcommit_memory = 1
609:M 12 Mar 2022 08:17:47.238 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add ‘vm.overcommit_memory = 1’ to /etc/sysctl.conf and then reboot or run the command ‘sysctl vm.overcommit_memory=1’ for this to take effect.
- 0表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存
申请失败,并把错误返回给应用进程。 - 1表示内核允许分配所有的物理内存,而不管当前的内存状态如何
- 2表示内核允许分配超过所有物理内存和交换空间总和的内存
WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command ‘echo never > /sys/kernel/mm/transparent_hugepage/enabled’ as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.d/rc.local
chmod +x /etc/rc.d/rc.local
配置参数解析
Redis 持久化
Redis 虽然是一个内存级别的缓存程序,也就是redis 是使用内存进行数据的缓存的,但是其可以将内存的数据按照一定的策略保存到硬盘上,从而实现数据持久保存的目的,目前redis支持两种不同方式的数据持久化保存机制,分别是RDB和AOF
RDB持久化
RDB持久化:可以在指定时间间隔内生成数据集的时间点快照(point-in-time snapshot)
AOF持久化
AOF持久化(AppendOnylFile):记录服务器执行的所有操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。AOF文件中的命令全部以redis协议的格式来保存,新命令会追加到文件的末尾。
优点 | 缺点 | |
---|---|---|
RDB | 1)基于时间的快照,默认持久化策略,执行速度快 2)可以最大化IO 的性能 因为父进程在保存RDB 文件的时候唯一要做的是fork出一个子进程,然后的-操作都会有这个子进程操作,父进程无需任何的IO操作RDB在大量数据比如几个G的数据,恢复的速度比AOF的快 | 可能会丢失从上次快照到当前时间点之间未做快照的数据 |
AOF | 1)数据安全性较高,fsync策略,默认是appendfsync everysec,即每秒执行一次fsync 2)日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果我们本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下一次启动之前,我们可以通过redis-check-aof工具来帮助我们解决数据一致性的问题 3)日志过大,Redis可以自动启用rewrite机制 4)AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作 | 1)即使有些操作是重复的也会全部记录,AOF的文件大小要大于RDB格式的文件 RDB 2)在恢复大数据集时的速度比 AOF 的恢复速度要快 3)AOF曾经出现过bug |
redis 数据类型
字符串(string)
set key value [expiration EX seconds|PX milliseconds] [NX|XX]
get key
del key [key ...]
mset key value [key value ...]
mget key [key ...]
APPEND key value
#数值递增减
192.168.3.49:6379> set num 10
OK
192.168.3.49:6379> INCR num
(integer) 11
192.168.3.49:6379> get num
"11"
192.168.3.49:6379> decr num
(integer) 10
192.168.3.49:6379> get num
"10"
#返回字符串key长度
strlen key
#判断key是否存在
exists key
#查看key的过期时间
TTL key
ttl #查看key的剩余生存时间
-1 #负一为永不过期,默认创建的key是永不过期,重新对key赋值,也会从有剩余生命周期变成永不过期
-2 #为没有此key
num #key的剩余有效期
#重新设置key的过期时间
EXPIRE key1 1000
#取消key的过期时间
PERSIST key1
列表(list)
列表是一个双向可读写的管道,其头部是左侧,尾部是右侧,一个列表最多可以包含2^32-1(4294967295)个元素,下标 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。 也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,元素值可以重复,常用于存入日志等场景,此数据类型比较常用。
LPUSH key value [value ...]
rpush key value [value ...]
lindex key index
lrange key start stop
lpop key
rpop key
ltrim key start r
del key [key ...]
集合(set)
Set 是 String 类型的无序集合,集合中的成员是唯一的,这就意味着集合中不能出现重复的数据,可以在两个不同的集合中对数据进行对比并取值,常用于取值判断,统计,交集等场景
sadd key member [member ...]
type key
smembers key
# 获取集合的交集
SINTER key [key ...]
#获取集合的并集
sunion key [key ...]
#获取集合的差集: 差集:已属于A而不属于B的元素称为A与B的差(集)
SDIFF key [key ...]
有序集合(sorted set)
Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员,不同的是每个元素都会关联一个double(双精度浮点型)类型的分数,redis正是通过该分数来为集合中的成员进行从小到大的排序,有序集合的成员是唯一的,但分数(score)却可以重复,集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1), 集合中最大的成员数为 2^32 – 1 (4294967295, 每个集合可存储40多亿个成员),经常用于排行榜的场景
zadd key [NX|XX] [CH] [INCR] score member [score member ...]
ZRANGE key start stop [WITHSCORES] #正序排序后显示集合内所有的key
ZREVRANGE key start stop [WITHSCORES] #倒序排序后显示集合内所有的key
zcard key #获取集合的长度数
zrange key start stop [WITHSCORES] #基于索引返回数值
zrank key member #返回某个数值的索引
哈希(hash)
hash 是一个string类型的field和value的映射表,redis 中每个 hash 可以存储 2^32 -1 键值对,类似于字典,存放了多个k/v 对,hash特别适合用于存储对象场景
hset key field value
hget key field
hmget key field [field ...] #获取hash key字段值
hdel key field [field ...] #删除一个hash key的字段
hkeys key #获取所有hash表中的key
hgetall key #获取指定hash的所有key及value
del key [key ...] #删除hash
raids 消息模式
消息队列主要分为两种,这两种模式Redis都支持
-
队列模式(queuing)
-
发布订阅模式(publish-subscribe)
任务队列
传递消息的队列。与任务队列交互的两种实体,一类生产者(producer),一类消费者(consumer)。生产者将需要处理的任务放入任务队列中,而消费者则不断的从任务队列中读入任务信息并执行。比较常用的消息队列软件还有RabbitMQ、Kafka、RocketMQ、ActiveMQ等。
-
生产者发布消息
127.0.0.1:6379> ping PONG 127.0.0.1:6379> LPUSH chanel1 mesg1 (integer) 1 127.0.0.1:6379> LPUSH chanel1 mesg2 (integer) 2 127.0.0.1:6379> LPUSH chanel1 mesg3 (integer) 3 127.0.0.1:6379> LPUSH chanel1 mesg4 (integer) 4 127.0.0.1:6379> LRANGE chanel1 0 -1 1) "mesg4" 2) "mesg3" 3) "mesg2" 4) "mesg1"
-
消费者消费消息
127.0.0.1:6379> RPOP chanel1 #从管道的右侧消费,用于消息的先进先出
"mesg1"
127.0.0.1:6379> RPOP chanel1
"mesg2"
127.0.0.1:6379> RPOP chanel1
"mesg3"
127.0.0.1:6379> RPOP chanel1
"mesg4"
127.0.0.1:6379> RPOP chanel1
(nil)
127.0.0.1:6379> LRANGE chanel 0 -1
(empty list or set) #队列中的消息已经被已全部消费完毕
127.0.0.1:6379>
发布者订阅模式
在发布者订阅者模式下,发布者将消息发布到指定的channel里面,凡是监听该channel的消费者都会收到同样的一份消息,这种模式类似于是收音机的广播模式,即凡是收听某个频道的听众都会收到主持人发布的相同的消息内容。此模式常用语群聊天、群通知、群公告等场景。
-
Publisher:发布者
-
Subscriber:订阅者
-
Channel:频道
- 订阅者监听频道
[root@host49 redis]# redis-cli -h 192.168.3.49 -p 6379 -a redis
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.3.49:6379> ping
PONG
192.168.3.49:6379> SUBSCRIBE channel1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel1"
3) (integer) 1
1) "message"
2) "channel1"
3) "msg1"
1) "message"
2) "channel1"
3) "msg2"
- 发布者发布消息
192.168.3.49:6379> PUBLISH channel1 msg1
(integer) 1
192.168.3.49:6379> PUBLISH channel1 msg2
(integer) 1
redis 常用命令
config
config 命令用于查看当前redis配置、以及不重启redis服务,动态更改redis配置等
192.168.3.49:6379> CONFIG SET maxmemory 8589934592
OK
192.168.3.49:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "8589934592"
192.168.3.49:6379> CONFIG SET requirepass redis
OK
192.168.3.49:6379>CONFIG GET * #获取当前配置 奇数行为键,偶数行为值
INFO
显示当前节点redis运行状态信息
# Server
redis_version:5.0.7
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:28915326d097554e
redis_mode:standalone
os:Linux 3.10.0-1160.el7.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:4.8.5
process_id:128809
run_id:14708e0d2f43160f687eda3c486df136e6260fe4
tcp_port:6379
uptime_in_seconds:17619
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:2921680
executable:/local/apps/redis/bin/redis-server
config_file:/local/apps/redis/etc/redis.conf
# Clients
connected_clients:2
client_recent_max_input_buffer:2
client_recent_max_output_buffer:0
blocked_clients:0
......
SELECT
切换数据库,等于MySQL的use DBNAME指令
KEYS
查看当前库下的所有key,此命令慎用!
BGSAVE
手动在后台执行RDB持久化操作
192.168.3.49:6379[2]> KEYS *
(empty list or set)
192.168.3.49:6379[2]> BGSAVE
Background saving started
192.168.3.49:6379[2]>
DBSIZE
返回当前库下的所有key 数量
FLUSHDB
强制清空当前库中的所有key
FLUSHALL
强制清空当前redis服务器所有数据库中的所有key,即删除所有数据