什么是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文件的目录
代码语言:javascript复制REPLICATION主从配置 SECURITY 安全 设置用户密码
# 用命令
config set requirepass "123456" #设置redis密码
auth 123456
config get requirepass #获取redis密码
代码语言:javascript复制CLIENTS 限制
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 : 永不过期,返回错误
代码语言:javascript复制APPEND ONLY MODE aof配置
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