Redis 详解

2022-12-28 21:03:05 浏览数 (1)

什么是Redis?

redis是一个开源的、使用C语言编写的、支持网络交互的、可基于内存也可持久化的Key-Value数据库。

Redis的功能

1、持久化 2、数据类型丰富 3、支持高可用 4、支持事务 5、多种内存分配及回收策略 6、消息队列、消息订阅 7、支持分布式分片集群 8、缓存穿透雪崩 9、Redis API

Redis优点

优点:高性能读写、多数据类型支持、数据持久化、高可用架构、支持自定义虚拟内存、支持分布式分片集群、单线程读写性能极高 适合,少用户访问,每个用户大量rw

使用场景

Redis:单核的缓存服务,单节点情况下,更加适合于少量用户,多次访问的应用场景。 Redis一般是单机多实例架构,配合redis集群出现。

redis安装部署

官网:https://redis.io

代码语言:javascript复制
[root@cs ~]# cd /home/xiaohei
[root@cs ~]# wget https://download.redis.io/releases/redis-5.0.13.tar.gz
[root@cs ~]# tar xf redis-5.0.13.tar.gz -C /opt/

安装:依赖包
[root@cs ~]# yum -y install gcc automake autoconf libtool make
[root@cs ~]# cd /opt/redis-5.0.13
[root@cs redis-5.0.13]# make
[root@cs redis-5.0.13]# cd /usr/local/bin
[root@cs bin]# ll
total 33796
-rwxr-xr-x 1 root root 1001112 Aug  5  2020 busybox-x86_64
-rw-r--r-- 1 root root     105 Sep 19 21:57 dump.rdb
-rwxr-xr-x 1 root root 4367032 Sep 19 18:54 redis-benchmark
-rwxr-xr-x 1 root root 8138736 Sep 19 18:54 redis-check-aof
-rwxr-xr-x 1 root root 8138736 Sep 19 18:54 redis-check-rdb
-rwxr-xr-x 1 root root 4808256 Sep 19 18:54 redis-cli
lrwxrwxrwx 1 root root      12 Sep 19 18:54 redis-sentinel -> redis-server
-rwxr-xr-x 1 root root 8138736 Sep 19 18:54 redis-server

#在这里我们创建一个自己的目录把redis.conf拷进来(防止玩崩了,可以恢复)
[root@cs bin]# mkdir xhconfig
[root@cs bin]# cp  /opt/redis-5.0.13/redis.conf xhconfig/
#启动redis
[root@cs bin]# redis-server xhconfig/redis.conf
25779:C 20 Sep 2021 19:03:28.090 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
25779:C 20 Sep 2021 19:03:28.090 # Redis version=5.0.13, bits=64, commit=00000000, modified=0, pid=25779, just started
25779:C 20 Sep 2021 19:03:28.090 # Configuration loaded

[root@cs bin]# redis-cli -p 6379   #redis默认 端口是6379
127.0.0.1:6379> 
127.0.0.1:6379> ping
PONG
# 退出
127.0.0.1:6379> shutdown
not connected> exit
[root@cs bin]# 

#环境变量:
#vim /etc/profile 
#export PATH=/data/redis/src:$PATH
#source /etc/profile 

Redis.conf详解

单位

包含

引用其他文件

网络

代码语言:javascript复制
bind 127.0.0.1      #绑定的IP
protected-mode yes  #保护模式
port 6379           #端口

通用

代码语言:javascript复制
daemonize yes     #守护进程(是否后台运行)默认是no,手动开启
pidfile /var/run/redis_6379.pid  #如果我们以守护进程开启,我们需要指定一个pid

#日志
# This can be one of:
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / critical messages are logged)
loglevel notice
logfile ""               #日志文件目录  (/var/log/redis.log)
databases 16             #数据库的数量
always-show-logo yes     #是否显示logo

快照

持久化,在规定时间,执行了多少操作,则会持久化到文件 .rdb .aof redis 是一个内存数据库,如果没有持久化,那么就会断电及失!

代码语言:javascript复制
# 如果900内 ,至少有一个key进行修改,我们就进行持久化操作
save 900 1
# 如果300内 ,至少有十个key进行修改,我们就进行持久化操作
save 300 10
# 如果60内 ,至少有一千个key进行修改,我们就进行持久化操作
save 60 10000

stop-writes-on-bgsave-error yes    #如果持久化出错,是否继续工作
rdbcompression yes                 #是否压缩rdb文件,需要消耗CPU资源
rdbchecksum yes                    #保存rdb文件时进行错误的检查校验
dir ./                             #保存rdb文件的目录

REPLICATION主从配置 SECURITY 安全 设置用户密码

代码语言:javascript复制
# 用命令
 config set requirepass "123456"   #设置redis密码
 auth 123456
 config get requirepass            #获取redis密码

CLIENTS 限制

代码语言:javascript复制
maxclients 10000   #redis连接数
maxmemory   #redis最大内存容量
maxmemory-policy noeviction   #内存达到上限之后的处理策略

1、volatile-lru:只对设置了过期时间的key进行LRU(默认值) 
2、allkeys-lru : 删除lru算法的key   
3、volatile-random:随机删除即将过期key   
4、allkeys-random:随机删除   
5、volatile-ttl : 删除即将过期的   
6、noeviction : 永不过期,返回错误

APPEND ONLY MODE aof配置

代码语言:javascript复制
appendonly no   #默认不开启,默认使用rdb
appendfilename "appendonly.aof"   ###持久化文件的名字

# appendfsync always    #每次都会执行sync 消耗性能
appendfsync everysec    #每秒执行一次sync 可能会丢失这1S数据
# appendfsync no        #不执行sync ,这个时候系统会自动同步数据,速度最快

Redis 命令

在远程服务上执行命令 如果需要在远程 redis 服务上执行命令,同样我们使用的也是 redis-cli 命令。

代码语言:javascript复制
语法
$ redis-cli -h host -p port -a password

Redis性能测试

代码语言:javascript复制
redis-benchmark -h 127.0.0.1 -p 6379 -t set,lpush -n 10000 -q

SET: 146198.83 requests per second
LPUSH: 145560.41 requests per second
Redis 键(key)

代码语言:javascript复制
127.0.0.1:6379> set mykey xiaohei            #创建mykey
OK
127.0.0.1:6379> get mykey                    #获取mykey
"xiaohei"
127.0.0.1:6379> del mykey                    #删除mykey
(integer) 1
127.0.0.1:6379> keys *                       #查看所有键
(empty list or set)
127.0.0.1:6379> set myskey "xiaohei"     
OK
127.0.0.1:6379> exists myskey                #键是否存在
(integer) 1
127.0.0.1:6379> 
127.0.0.1:6379> FLUSHALL                     #清除所有库的键
OK
127.0.0.1:6379> FLUSHDB                      #清除本库的键
127.0.0.1:6379> set mykey "xiaohei"
OK
127.0.0.1:6379> EXPIRE mykey 10              #设置10秒后过期
(integer) 1
127.0.0.1:6379> ttl mykey                    #显示剩余时间
(integer) 8
127.0.0.1:6379> ttl mykey
(integer) 5
127.0.0.1:6379> ttl mykey
(integer) 2
127.0.0.1:6379> ttl mykey
(integer) -2
127.0.0.1:6379> PERSIST mykey                #清除过期时间
(integer) 1
127.0.0.1:6379> ttl mykey
(integer) -1
127.0.0.1:6379> move mykey 2                 #移动到指定的数据库
(integer) 1
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> select 2                     #进入指定数据库
OK
127.0.0.1:6379[2]> keys *
1) "mykey"
127.0.0.1:6379> set mykey "xiaohei"
OK
127.0.0.1:6379> set k1 "hello"
OK
127.0.0.1:6379> set k2 "world"
OK
127.0.0.1:6379> RANDOMKEY                   #随机显示一个key
"mykey"
127.0.0.1:6379> RANDOMKEY
"mykey"
127.0.0.1:6379> RANDOMKEY
"k2"
127.0.0.1:6379> RANDOMKEY
"mykey"
127.0.0.1:6379> RANDOMKEY
"mykey"
127.0.0.1:6379> RANDOMKEY
"k2"
127.0.0.1:6379> RANDOMKEY
"k1"
127.0.0.1:6379> RENAME k1 kk               #修改key名
OK
127.0.0.1:6379> keys *
1) "kk"
2) "k2"
3) "mykey"
127.0.0.1:6379> type mykey                 #显示key的值的类型
string

Redis 字符串(String)

代码语言:javascript复制
127.0.0.1:6379> SET mykey "This is my test key"       
OK
127.0.0.1:6379> GETRANGE mykey 0 3         #截取字符串[0,3]
"This"
127.0.0.1:6379> GETRANGE mykey 0 -1        #截取全部
"This is my test key"
127.0.0.1:6379> APPEND mykey "hello"       #追加,如果这个key不存在则会创建一个key 
(integer) 24
127.0.0.1:6379> get mykey              
"This is my test keyhello"
127.0.0.1:6379> STRLEN mykey               #返回字符串值的长度
(integer) 24
# !替换
127.0.0.1:6379> set mykey "abcdefg"
OK
127.0.0.1:6379> SETRANGE mykey 2 xxx       #从第二个开始替换
(integer) 7
127.0.0.1:6379> get mykey
"abxxxfg"
###################################################################################################
# i  
# 步长 i =
127.0.0.1:6379> set views 0                #初始量0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incr views                 #每次自加1
(integer) 1
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> get views
"2"
127.0.0.1:6379> decr views                 #每次自减1
(integer) 1
127.0.0.1:6379> decr views
(integer) 0
127.0.0.1:6379> decr views
(integer) -1
127.0.0.1:6379> get views
"-1"
127.0.0.1:6379> INCRBY views 10           #指定增量
(integer) 9
127.0.0.1:6379> INCRBY views 10
(integer) 19
127.0.0.1:6379> DECRBY views 5            #指定减量
(integer) 14
###################################################################################################
# setex 设置过期时间
# setnx 不存在再设置
127.0.0.1:6379> SETEX mykey 30 "xiaohei"  #设置一个mykey 30秒过期
OK
127.0.0.1:6379> ttl mykey               
(integer) 25
127.0.0.1:6379> get mykey
"xiaohei"
127.0.0.1:6379> setnx k1 "redis"          #不存在则创建一个key
(integer) 1
127.0.0.1:6379> keys *
1) "k1"
127.0.0.1:6379> ttl mykey
(integer) -2
127.0.0.1:6379> setnx k1 "mongodb"        #存在则操作失败
(integer) 0
127.0.0.1:6379> get k1
"redis"
###################################################################################################
# mset
# mget
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3    #创建多个key
OK
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"
127.0.0.1:6379> mget k1 k2 k3             #查询多个key
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k1 v1 k4 v4        #要么一起成功,要么一起失败
(integer) 0
127.0.0.1:6379> get k4
(nil)

#对象
127.0.0.1:6379> set user:1 {name:zhangsan,age:18}      #设置一个user:1 对象 值为json字符来保存一个对象
OK
127.0.0.1:6379> get user:1
"{name:zhangsan,age:18}"
127.0.0.1:6379> mset user:1:name lisi user:1:age 18    # 设置一个user:{id}:{filed}
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "lisi"
2) "18"
###################################################################################################
getset  #先get在set
127.0.0.1:6379> getset db redis             #如果不存在值则返回空
 (nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mongodb           #如果存在则返回原来的值,在覆盖新的值
"redis"
127.0.0.1:6379> get db
"mongodb"

数据结构是相同的! string类似的使用场景:value 除了字符串还可以是数字

  • 计数器
  • 统计多单位的数量
  • 粉丝数
  • 对象缓存存储

Redis 列表(List)

Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)

代码语言:javascript复制
127.0.0.1:6379> LPUSH mykey "redis"        #将一个或者多个值,插入列表头部(左)
(integer) 1
127.0.0.1:6379> LPUSH mykey "mongodb"
(integer) 2
127.0.0.1:6379> LPUSH mykey "mysql"
(integer) 3
127.0.0.1:6379> LRANGE mykey 0 1
1) "mysql"
2) "mongodb"
127.0.0.1:6379> RPUSH mykey "MariaDB"      #将一个或者多个值,插入列表头部(右)
(integer) 4
127.0.0.1:6379> LRANGE mykey 0 -1
1) "mysql"
2) "mongodb"
3) "redis"
4) "MariaDB"

###################################################################################################
LPOP
RPOP
127.0.0.1:6379> LPOP mykey                #移除(左)
"mysql"
127.0.0.1:6379> RPOP mykey                #移除(右)
"MariaDB"
127.0.0.1:6379> LRANGE mykey 0 -1
1) "mongodb"
2) "redis"
###################################################################################################
LINSDEX
127.0.0.1:6379> LINDEX mykey 0            #通过下标获取list中的某个值
"mongodb"
127.0.0.1:6379> LINDEX mykey 1
"redis"
###################################################################################################
LLEN
127.0.0.1:6379> LLEN mykey               #获取列表长度
(integer) 3
###################################################################################################
LREM
127.0.0.1:6379> LRANGE mykey 0 -1         #LPUSH 可以出现重复的值
1) "redis"
2) "mongodb"
3) "redis"
4) "mysql"
5) "mongodb"
6) "redis"
127.0.0.1:6379> LREM mykey 1 redis        #移除1个redis
(integer) 1
127.0.0.1:6379> LRANGE mykey 0 -1 
1) "mongodb"
2) "redis"
3) "mysql"
4) "mongodb"
5) "redis"
127.0.0.1:6379> LREM mykey 2 mongodb       #移除两个mongodb
(integer) 2
127.0.0.1:6379> LRANGE mykey 0 -1
1) "redis"
2) "mysql"
3) "redis"
###################################################################################################
LTRIM
127.0.0.1:6379> LRANGE mykey 0 -1
1) "redis"
2) "mysql"
3) "redis"
127.0.0.1:6379> LTRIM mykey 0 1           #修剪,截断
OK
127.0.0.1:6379> LRANGE mykey 0 -1
1) "redis"
2) "mysql"
###################################################################################################
RPOPLPUSH   移除列表最后一个,并且移动到新的列表
127.0.0.1:6379> LRANGE mykey 0 -1
1) "mongodb"
2) "redis"
3) "mysql"
127.0.0.1:6379> RPOPLPUSH mykey key       #移除列表最后一个,并且移动到新的列表
"mysql"
127.0.0.1:6379> LRANGE mykey 0 -1
1) "mongodb"
2) "redis"
127.0.0.1:6379> LRANGE key 0 -1
1) "mysql"
###################################################################################################
LSET  将列表中存在的值替换成另外的一个值,更新操作
127.0.0.1:6379> LRANGE mykey 0 -1
1) "mongodb"
2) "redis"
127.0.0.1:6379> LSET mykey 0 mysql         #将列表中存在的值替换成另外的一个值,更新操作(值必须存在,不存在则报错)
OK
127.0.0.1:6379> LRANGE mykey 0 -1
1) "mysql"
2) "redis"
###################################################################################################
LINSERT   #在列表指定值前面或者后面插入一个新值
127.0.0.1:6379> LRANGE mykey 0 -1
1) "mysql"
2) "redis"
127.0.0.1:6379> LINSERT mykey before "redis" "mongodb"    #在列表指定值前面插入一个新值
(integer) 3
127.0.0.1:6379> LRANGE mykey 0 -1
1) "mysql"
2) "mongodb"
3) "redis"
127.0.0.1:6379> LINSERT mykey after "redis" "maridb"      ##在列表指定值后面插入一个新值
(integer) 4
127.0.0.1:6379> LRANGE mykey 0 -1
1) "mysql"
2) "mongodb"
3) "redis"
4) "maridb"

Redis 集合(Set)

Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。 集合对象的编码可以是 intset 或者 hashtable。 Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。

代码语言:javascript复制
127.0.0.1:6379> sadd mykey "hello"          #set集合中添加值
(integer) 1
127.0.0.1:6379> sadd mykey "xiaohei"
(integer) 1
127.0.0.1:6379> sadd mykey "123456"
(integer) 1
127.0.0.1:6379> SMEMBERS mykey              #查看set的所有值
1) "123456"
2) "xiaohei"
3) "hello"
127.0.0.1:6379> SISMEMBER mykey hello       #判断一个值是否存在set集合里面
(integer) 1
127.0.0.1:6379> SISMEMBER mykey world
(integer) 0
127.0.0.1:6379> SCARD mykey                  #判断set集合里面的元素个数
(integer) 3
127.0.0.1:6379> SREM mykey 123456            #移除一个元素
(integer) 1
127.0.0.1:6379> SMEMBERS mykey
1) "xiaohei"
2) "hello"
127.0.0.1:6379> SRANDMEMBER mykey            #随机显示一个元素
"xiaohei"
127.0.0.1:6379> SRANDMEMBER mykey 
"hello"

127.0.0.1:6379> sadd mykey "xiaohei" "hello" "world"
(integer) 3
127.0.0.1:6379> SMEMBERS mykey
1) "world"
2) "hello"
3) "xiaohei"
127.0.0.1:6379> spop mykey                  #随机删除一个元素
"world"
127.0.0.1:6379> spop mykey
"xiaohei"
127.0.0.1:6379> SMEMBERS mykey
1) "hello"
###################################################################################
127.0.0.1:6379> sadd mykey "xiaohei" "hello" "world"
(integer) 3
127.0.0.1:6379> SMEMBERS mykey
1) "world"
2) "hello"
3) "xiaohei"
127.0.0.1:6379> sadd k1 "12345" "abcdefg"
(integer) 2
127.0.0.1:6379> SMEMBERS k1
1) "12345"
2) "abcdefg"
127.0.0.1:6379> SMOVE mykey k1 xiaohei            #指定一个元素,移动到另一个集合
(integer) 1
127.0.0.1:6379> SMEMBERS k1
1) "12345"
2) "abcdefg"
3) "xiaohei"
127.0.0.1:6379> SMEMBERS mykey
1) "world"
2) "hello"
###################################################################################
127.0.0.1:6379> SMEMBERS mykey
1) "world"
2) "xiaohei"
3) "hello"
127.0.0.1:6379> SMEMBERS k1
1) "12345"
2) "abcdefg"
3) "xiaohei"
127.0.0.1:6379> sinter mykey k1            #显示共同的值(交)
1) "xiaohei"
127.0.0.1:6379> sunion mykey k1            #显示不相同的值(并)
1) "world"
2) "hello"
3) "xiaohei"
4) "12345"
5) "abcdefg"

Redis 哈希(Hash)

Redis hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。

代码语言:javascript复制
127.0.0.1:6379> hset myhash field1 xiaohei           #set一个值
(integer) 1
127.0.0.1:6379> hget myhash field1                   #获取一个字段的值
"xiaohei"
127.0.0.1:6379> hmset myhash field1 hello field2 world   #set多个值
OK
127.0.0.1:6379> hmget myhash field1 field2                #获取多个值
1) "hello"
2) "world"
127.0.0.1:6379> hgetall myhash                            #获取全部元素
1) "field1"
2) "hello"
3) "field2"
4) "world"
###################################################################################
127.0.0.1:6379> hdel myhash field2            #删除字段
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "field1"
2) "hello"
###################################################################################
127.0.0.1:6379> hgetall myhash
1) "field1"
2) "hello"
127.0.0.1:6379> hlen myhash                #获取hash表的字段数量
(integer) 1
###################################################################################
127.0.0.1:6379> HEXISTS myhash field1      #判断hash表中是否存在字段
(integer) 1
127.0.0.1:6379> HEXISTS myhash field2
(integer) 0
###################################################################################
127.0.0.1:6379> hkeys myhash               #获取所有field
1) "field1"
127.0.0.1:6379> hvals myhash               #获取所有value
1) "hello"

###################################################################################
127.0.0.1:6379> hset myhash field3 5        #指定增量
(integer) 1
127.0.0.1:6379> HINCRBY myhash field3 1
(integer) 6
127.0.0.1:6379> HINCRBY myhash field3 1
(integer) 7
127.0.0.1:6379> HINCRBY myhash field3 -1
(integer) 6
127.0.0.1:6379> HSETNX myhash field4 hello  #如果不存在则创建
(integer) 1
127.0.0.1:6379> HSETNX myhash field4 world  #存在则失败
(integer) 0

hash变更的数据 user name age ,尤其是用户信息之类的,经常变动的信息hashsh更适合对象存储

zset(有序集合)

代码语言:javascript复制
127.0.0.1:6379> zadd myset 1 one           #添加值
(integer) 1
127.0.0.1:6379> zadd myset 2 two 3 tree    #添加多个值
(integer) 2
127.0.0.1:6379> ZRANGE myset 0 -1
1) "one"
2) "two"
3) "tree"
###################################################################################
排序
127.0.0.1:6379> zadd salary 2500 xiaohong              #创建三个用户
(integer) 1
127.0.0.1:6379> zadd salary 5000 zhangsan 500lisi
(error) ERR syntax error
127.0.0.1:6379> zadd salary 5000 zhangsan
(integer) 1
127.0.0.1:6379> zadd salary 500 lisi
(integer) 1
127.0.0.1:6379> ZRANGEBYSCORE salary -inf  inf        #显示全部,从小到大排序
1) "lisi"
2) "xiaohong"
3) "zhangsan"
127.0.0.1:6379> ZREVRANGE salary 0 -1                 #从大到小
1) "zhangsan"
2) "lisi"
127.0.0.1:6379> ZRANGEBYSCORE salary -inf  inf withscores   ##显示全部,并且附带
1) "lisi"
2) "500"
3) "xiaohong"
4) "2500"
5) "zhangsan"
6) "5000"
127.0.0.1:6379> ZRANGEBYSCORE salary -inf 2500 withscores   ##显示到2500的用户
1) "lisi"
2) "500"
3) "xiaohong"
4) "2500"
###################################################################################
127.0.0.1:6379> ZRANGE salary 0 -1
1) "lisi"
2) "xiaohong"
3) "zhangsan"
127.0.0.1:6379> ZREM salary xiaohong      #移除有序集合的指定元素
(integer) 1
127.0.0.1:6379> ZRANGE salary 0 -1
1) "lisi"
2) "zhangsan"
127.0.0.1:6379> ZCARD salary             #获取有序集合的元素个数
(integer) 2

###################################################################################
127.0.0.1:6379> zadd k1 1 hello 2 world 3 xiaohei
(integer) 3
127.0.0.1:6379> ZCOUNT k1 1 3           #获取指定区间的成员数量
(integer) 3
127.0.0.1:6379> ZCOUNT k1 1 2
(integer) 2

0 人点赞