Linux-云计算-Redis基础入门
目录
1.非关系型数据库(NoSQL)
1.简介
随着数据量和访问量的增加,传统Web应用依赖的RDBMS(关系数据库管理系统)会出现负载加重、响应变慢、页面延迟等问题。为提升性能,通常引入非关系型数据库(NoSQL),如Redis、Memcached,作为高性能分布式缓存服务器,通过缓存数据库查询结果,减少对RDBMS的访问,提升系统响应速度和可扩展性。需要注意的是,非关系型数据库不仅用于缓存,还可用于存储海量文档、键值数据、图数据等不同场景。
在服务集群中一般位于数据库的前面
Web服务器(Nginx),Web(Tomcat),数据库缓存(Redis),数据库(MySQL)
2.分类
非关系型数据库(NoSQL)分类主要有四种:
1. 键值存储(Key-Value Store)
-
- 特点:用唯一键(Key)快速访问对应的值(Value)。简单、高效,常用于缓存。
- 代表产品:Redis、Memcached、Riak
- 应用场景:缓存、会话管理、排行榜系统。
2. 文档型存储(Document Store)
-
- 特点:以文档(通常是 JSON、BSON、XML 格式)形式存储,支持复杂查询和灵活结构。
- 代表产品:MongoDB、CouchDB
- 应用场景:内容管理系统(CMS)、电商商品数据。
3. 列族存储(Column-Family Store)
-
- 特点:以列簇(Column Family)方式存储数据,适合海量数据存储和快速查询某些列。
- 代表产品:HBase、Cassandra、ScyllaDB
- 应用场景:大数据分析、日志系统、用户画像。
4. 图数据库(Graph Database)
-
- 特点:以节点(Node)+ 边(Edge)存储数据,擅长处理复杂的关联关系。
- 代表产品:Neo4j、ArangoDB、JanusGraph
- 应用场景:社交网络、推荐系统、知识图谱。
3.NoSQL作用
如果应用传统上直接从RDBMS读取数据,随着并发和数据量增加,会导致:
- 数据库负载加重
- 响应速度变慢
- 页面访问延迟
解决方案:
1. 增加数据库集群规模,扩展更多数据库节点来分摊压力。
2. 引入缓存技术(如Redis),缓存热点数据,减少数据库访问次数,从而缓解RDBMS的压力并提升整体系统性能。
2.Redis
1.Redis基础
1.Redis简介
Redis是一个高性能的内存数据库,具有丰富的数据结构(如List、Set、Hash等),支持持久化保存数据到磁盘,支持事务操作,保证一组命令要么全部成功、要么全部失败,同时支持主从复制、高可用(哨兵)、分布式分片集群,适用于缓存、实时计算和分布式系统等多种场景。
2.Redis帮助
官方网站:https://redis.io
Redis的官网:redis.io 注:域名后缀io属于国家域名,是british Indian Ocean territory,即英属印度洋领地
官方各版本下载地址:Index of /releases/
Redis 中文命令参考:http://redisdoc.com
中文网站1:http://redis.cn
中文网站2:http://www.redis.net.cn
2.Redis安装
1.YUM安装
安装仓库
[root@leokon ~]# yum -y install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
安装Redis并启动
[root@leokon ~]# yum -y --enablerepo=remi install redis
[root@leokon ~]# systemctl start redis
设置redis.conf,允许远程登录
[root@leokon ~]# vim /etc/redis.conf
bind 127.0.0.1 改为 bind 0.0.0.0 (可选)
登录
[root@leokon ~]# systemctl restart redis
[root@leokon ~]# redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> set name xingdian
OK
127.0.0.1:6379> get name
"xingdian"
127.0.0.1:6379>
2.编译安装
下载源码包
[root@leokon ~]# wget https://download.redis.io/redis-stable.tar.gz
[root@leokon ~]# tar xvzf redis-stable.tar.gz -C /usr/local/
安装编译所需软件
[root@leokon ~]# yum install -y gcc-c++ autoconf automake make
编译和安装
leokonroot@xingdian redis-stable]# make && make install
启动
[root@leokon redis-stable]# cd src/
[root@leokon src]# ./redis-server &
3.Redis使用
1.Redis工具
./redis-benchmark #用于进行redis性能测试的工具
./redis-check-rdb #用于修复出问题的dump.rdb文件
./redis-cli #redis的客户端
./redis-server #redis的服务端
./redis-check-aof #用于修复出问题的AOF文件
./redis-sentinel #用于集群管理
2.Redis配置文件
1、是否后台运行
daemonize no/yes # yes 表示后台运行,常用于生产环境
2、默认端口
port 6379
3、AOF 日志开关是否打开
appendonly no/yes # 开启 AOF 持久化,记录每条写操作日志
4、日志文件位置
logfile /var/log/redis.log # Redis 日志输出路径
5、RDB 持久化数据文件
dbfilename dump.rdb # 默认的 RDB 数据文件名
6、指定IP进行监听
bind 10.0.0.51 ip2 ip3 ip4 # 指定 Redis 服务监听的地址,支持多个
7、禁止protected-mode
protected-mode yes/no (保护模式,是否只允许本地访问) # 默认 yes,只允许本地连接
8、增加requirepass {password}
requirepass root # 设置 Redis 连接密码,提高安全性
9、在redis-cli中使用
redis-cli -a yourpassword # 使用密码登录
3.数据持久化
1.持久化方式
方式一:RDB(Redis DataBase)
RDB 是在不同时间点生成内存快照并保存到磁盘的机制,优点是备份效率高、支持一次性还原所有数据,并不会影响主线程读写,因为是由子进程异步完成备份。但缺点是数据不是实时保存的,故障可能导致上次快照之后的数据丢失,数据完整性相对较差。
方式二:AOF(Append Only File)
AOF 是通过记录 Redis 执行过的所有写命令来实现持久化,重启时通过重放这些命令恢复数据。它的优点是数据恢复更完整、实时性更高,但缺点是文件体积大、恢复速度较慢。
两者结合使用(推荐)
Redis 支持同时开启 RDB 和 AOF。默认情况下 Redis 优先使用 AOF 文件恢复数据,以确保数据完整性,而 RDB 作为补充,提升系统容错能力。官方也推荐同时开启两者,以实现更安全可靠的持久化方案。
使用建议:
- 如果 Redis 仅用作缓存,可关闭持久化,获得最高性能。
- 如果对数据完整性有要求,建议同时开启 AOF 和 RDB,AOF 提供实时持久化,RDB 作为备份手段。
- 在只选其一的情况下,追求性能选 RDB,追求数据安全选 AOF
写入速度快 ------------AOF
写入速度慢 ------------RDB
2.持久化配置
1.RDB
1.RDB持久化
[root@leokon ~]# vim /etc/redis.conf
# RDB 持久化文件名称(保存快照的文件名)
dbfilename dump.rdb
# 持久化数据存储的本地目录路径(必须存在且Redis有写权限)
dir /var/lib/redis
# 快照触发条件(save <seconds> <changes>):
# 表示在指定秒数内发生指定数量的写操作,就触发一次快照(RDB持久化)
save 900 1 # 900秒内有1个key被修改,触发保存
save 300 10 # 300秒内有10个key被修改,触发保存
save 60 10000 # 60秒内有10000个key被修改,触发保存
# 如需关闭快照持久化(不推荐在线上使用),可使用:
# save ""
# 快照保存失败(如磁盘满、文件写失败等)时,是否停止写操作(默认 yes)
stop-writes-on-bgsave-error yes
# 是否启用RDB文件压缩(默认为 yes)
# 启用后将使用LZF压缩算法压缩RDB文件,节省磁盘空间和网络传输带宽,但会增加CPU负担
rdbcompression yes
2.RDB持久化单次启动
Redis 后台存储通过 BGSAVE 命令触发,由子进程执行快照,不阻塞主线程,适合生产环境;而前台存储使用 SAVE 命令,直接由主线程执行,会阻塞客户端请求,仅用于调试或临时备份。
redis-cli BGSAVE # 后台生成快照(推荐)
redis-cli SAVE # 前台生成快照(会阻塞)
2.AOF
1.AOF持久配置
- `appendonly yes/no`
是否打开 AOF 日志功能。
- `appendfsync always`
每执行 1 个命令,都立即同步到 AOF 文件。
- `appendfsync everysec`
每秒写 1 次。
- `appendfsync no`
写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入到 AOF 文件。
- `no-appendfsync-on-rewrite yes/no`
正在导出 RDB 快照的过程中,要不要停止同步 AOF。
- `auto-aof-rewrite-percentage 100`
AOF 文件大小比起上次重写时的大小,增长率达到 100% 时重写。
缺点:业务开始的时候,会重复重写多次。
- `auto-aof-rewrite-min-size 64mb`
AOF 文件至少超过 64MB 时,才允许重写。
+
3.RDB到AOF切换
1、为最新的 dump.rdb 文件创建一个备份。
2、将备份放到一个安全的地方。
3、执行以下两条命令:
redis-cli config set appendonly yes
redis-cli config set save “”
4、确保写命令会被正确地追加到 AOF 文件的末尾
#注意!!!!
执行的第一条命令开启了 AOF 功能: Redis 会阻塞直到初始 AOF 文件创建完成为止, 之后 Redis 会继续处理命令请求, 并开始将写入命令追加到 AOF 文件末尾
执行的第二条命令用于关闭 RDB 功能。 这一步是可选的, 如果你愿意的话, 也可以同时使用 RDB 和 AOF 这两种持久化功能
别忘了在 redis.conf 中打开 AOF 功能! 否则的话, 服务器重启之后, 之前通过 CONFIG SET 设置的配置不会生效, 程序会按原来的配置来启动服务器
4.数据恢复
将需要恢复数据的新机器的redis关闭,将数据放到新机器指定的目录下,并覆盖,然后重新启动redis即可
4.Redis数据类型
1.基本数据类型
| 类型 | 说明 |
| String 字符串 | Redis 字符串数据类型的相关命令用于管理 redis 字符串值 |
| Hash 哈希 | Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。Redis 中每个 hash 可以存储 (2的32次方)2^32 - 1 键值对(40多亿)。 |
| List 列表 | Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边) 一个列表最多可以包含 2^32 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。 |
| Set 集合 | Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。 |
| Sorted set 有序集合 | Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。 |
2.Redis命令帮助
运行redis-cli连接服务器->执行help
127.0.0.1:6379> help
redis-cli 6.0.7
To get help about Redis commands type:
"help @<group>" to get a list of commands in <group>
"help <command>" for help on <command>
"help <tab>" to get a list of possible help topics
"quit" to exit
To set redis-cli preferences:
":set hints" enable online hints
":set nohints" disable online hints
Set your preferences in ~/.redisclirc
根据输出可以看到 help 命令有三种用法
“help @<group>” to get a list of commands in <group>,
”help <command>” for help on <command>,
”help <tab>” to get a list of possible help topics
help @ 查看命令组的帮助
help @generic 查看通用组的命令包括del,dump…等等通用命令。
help @string 查看字符串组命令。还可以查看其他组的命令如help @list, help @set, help @sorted_set,help @hash 等等。
查看所有的分组可以通过help <tab>提示。
help 查看具体命令的用法
help 具体命令可以查看命令的用法描述,命令从那个版本开始,命令属于哪个组等信息。如 help get
help @generic
127.0.0.1:6379> help @generic
DEL key [key ...]
summary: Delete a key
since: 1.0.0
DUMP key
summary: Return a serialized version of the value stored at the specified key.
since: 2.6.0
EXISTS key [key ...]
summary: Determine if a key exists
since: 1.0.0
EXPIRE key seconds
summary: Set a key's time to live in seconds
since: 1.0.0
EXPIREAT key timestamp
summary: Set the expiration for a key as a UNIX timestamp
since: 1.2.0
KEYS pattern
summary: Find all keys matching the given pattern
since: 1.0.0
MIGRATE host port key| destination-db timeout [COPY] [REPLACE] [AUTH password] [KEYS key]
summary: Atomically transfer a key from a Redis instance to another one.
since: 2.6.0
MOVE key db
summary: Move a key to another database
since: 1.0.0
OBJECT subcommand [arguments [arguments ...]]
summary: Inspect the internals of Redis objects
since: 2.2.3
PERSIST key
summary: Remove the expiration from a key
since: 2.2.0
PEXPIRE key milliseconds
summary: Set a key's time to live in milliseconds
since: 2.6.0
PEXPIREAT key milliseconds-timestamp
summary: Set the expiration for a key as a UNIX timestamp specified in milliseconds
since: 2.6.0
PTTL key
summary: Get the time to live for a key in milliseconds
since: 2.6.0
RANDOMKEY -
summary: Return a random key from the keyspace
since: 1.0.0
RENAME key newkey
summary: Rename a key
since: 1.0.0
RENAMENX key newkey
summary: Rename a key, only if the new key does not exist
since: 1.0.0
RESTORE key ttl serialized-value [REPLACE] [ABSTTL] [IDLETIME seconds] [FREQ frequency]
summary: Create a key using the provided serialized value, previously obtained using DUMP.
since: 2.6.0
SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]
summary: Incrementally iterate the keys space
since: 2.8.0
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination]
summary: Sort the elements in a list, set or sorted set
since: 1.0.0
TOUCH key [key ...]
summary: Alters the last access time of a key(s). Returns the number of existing keys specified.
since: 3.2.1
TTL key
summary: Get the time to live for a key
since: 1.0.0
TYPE key
summary: Determine the type stored at key
since: 1.0.0
UNLINK key [key ...]
summary: Delete a key asynchronously in another thread. Otherwise it is just as DEL, but non blocking.
since: 4.0.0
WAIT numreplicas timeout
summary: Wait for the synchronous replication of all the write commands sent in the context of the current connection
since: 3.0.0
GEORADIUSBYMEMBER_RO key arg arg arg ...options...
summary: Help not available
since: not known
SUBSTR key arg arg
summary: Help not available
since: not known
PFDEBUG arg arg ...options...
summary: Help not available
since: not known
BITFIELD_RO key ...options...
summary: Help not available
since: not known
HOST: ...options...
summary: Help not available
since: not known
XSETID key arg
summary: Help not available
since: not known
ASKING
summary: Help not available
since: not known
GEORADIUS_RO key arg arg arg arg ...options...
summary: Help not available
since: not known
REPLCONF ...options...
summary: Help not available
since: not known
PFSELFTEST
summary: Help not available
since: not known
RESTORE-ASKING key arg arg ...options...
summary: Help not available
since: not known
POST ...options...
summary: Help not available
since: not known
3.Redis全局Key操作
| 命令 | 含义 |
| KEYS * | 查看KEY支持通配符 |
| DEL | 删除给定的一个或多个key |
| EXISTS | 检查是否存在 |
| RENAME | 变更KEY名 |
| SORT | 键值排序,有非数字时报错 |
| TYPE | 返回键所存储值的类型 |
| DUMP RESTORE | 序例化与反序列化 |
| EXPIRE\ PEXPIRE | 以秒\毫秒设定生存时间 |
| TTL\ PTTL | 以秒\毫秒为单位返回生存时间 |
| PERSIST | 取消生时间设置 |
| RANDOMKEY | 返回数据库中的任意键 |
1.del 命令
del 命令用来 删除指定的一个或多个 key
删除一个 key
127.0.0.1:6379> set test 1234
127.0.0.1:6379> del test
删除多个 key
127.0.0.1:6379> mset test1 1111 test2 2222
127.0.0.1:6379> del test1 test2
2.exists 命令
exists 命令用来查询 key 是否存在
127.0.0.1:6379> mset test1 1111 test2 2222
192.168.152.133:6379> EXISTS test1
(integer) 1
3.expire 命令
expire 命令用来 设置 key 的过期秒数
127.0.0.1:6379> get test1
与 expire 命令相关的命令有三个,分别是:
1.expireat
用来设置一个 UNIX 时间戳的过期时间, (从1970年1月1日0时0分0秒到你设置过期的秒数)
127.0.0.1:6379> EXPIREAT test2 1592965943
(integer) 1
2.pexpire
用来设置 key的有效时间以毫秒为单位
127.0.0.1:6379> EXPIRE test3 100
(integer) 1
127.0.0.1:6379> ttl test3
(integer) 94
127.0.0.1:6379> pttl test3
(integer) 89235
3.pexpireat
用来设置 key 的到期 UNIX 时间戳以毫秒为单位
127.0.0.1:6379> PEXPIREAT test3 1592965943000
(integer) 1
192.168.152.133:6379> ttl test3
(integer) 365
4.keys 命令
keys 命令用来 查找所有匹配给定的模式的键
127.0.0.1:6379> keys *
1) "a"
2) "test"
3) "test1"
4) "name"
在 Redis 中是支持模糊查询的,它有 3 个通配符,分别是:*、 ? 和 []
*:通配任意多个字符
?:通配单个字符
[]:通配括号内的某 1 个字符
[] 的用法如下:
127.0.0.1:6379> keys *[s]*
1) "test"
2) "test1"
127.0.0.1:6379> keys *[a]*
1) "a"
2) "name"
? 的用法如下:
127.0.0.1:6379> set a bbb
OK
127.0.0.1:6379> keys ?
1) "a"
5.ttl 命令
ttl 命令用来 获取 key 的有效时间(单位:秒)
127.0.0.1:6379> get test1
上面的命令是,我们用 expire 对一个 key 设置一个过期时间,然后使用 ttl 观察它的剩余时间
ttl 一个 key,如果返回 -1,则说明该 key 不会过期
ttl 一个 key,如果返回 -2,则说明没有指定的 key
与 ttl 相关的命令是 pttl 命令,它用来 获取 key 的有效毫秒数
4.Redis String(字符串)
string是redis最基本的类型,一个key对应一个value。一个键最大能存储 512MB。
| 命令 | 描述 |
| SET key value | 设置指定 key 的值 |
| GET key | 获取指定 key 的值。 |
| GETRANGE key start end | 返回 key 中字符串值的子字符 |
| GETSET key value | 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。 |
| GETBIT key offset**对 key** | 所储存的字符串值,获取指定偏移量上的位(bit)。 |
| MGET key1 [key2..] | 获取所有(一个或多个)给定 key 的值。 |
| SETBIT key offset value | 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。 |
| SETEX key seconds value | 将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。 |
| SETNX key value | 只有在 key 不存在时设置 key 的值。 |
| SETRANGE key offset value | 用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始。 |
| STRLEN key | 返回 key 所储存的字符串值的长度。 |
| MSET key value [key value ...] | 同时设置一个或多个 key-value 对。 |
| MSETNX key value [key value ...] | 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。 |
| PSETEX key milliseconds value | 这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。 |
| INCR key | 将 key 中储存的数字值增一。 |
| INCRBY key increment | 将 key 所储存的值加上给定的增量值(increment) 。 |
| INCRBYFLOAT key increment | 将 key 所储存的值加上给定的浮点增量值(increment) 。 |
| DECR key | 将 key 中储存的数字值减一。 |
| DECRBY key decrementkey | 所储存的值减去给定的减量值(decrement) 。 |
| APPEND key value | 如果 key 已经存在并且是一个字符串, APPEND 命令将 指定value 追加到改 key 原来的值(value)的末尾。 |
1.SET
1.语法
SET key value [EX seconds] [PX milliseconds] [NX|XX]
将字符串值 value 关联到键 key。
如果 key 已存在,不管之前是什么类型或值,都会被覆盖。
若 key 原本设置了 TTL,执行 SET 会清除原有的过期时间。
使用 NX:仅当键不存在时才设置。
使用 XX:仅当键已存在时才设置。
返回值:
成功时返回 "OK"。
使用 NX 或 XX 条件未满足时,返回空(nil)。
2.代码示例
● 对不存在的键进行设置:
redis> SET key "value"
OK
redis> GET key
● "value"对已存在的键进行设置:
redis> SET key "new-value"
OK
redis> GET key
"new-value"
5.Redis Hash(字典)
1.HSET
键值对结构:String -> String,类似 Map。
适合存储对象数据,如用户信息(username、password、age)。
存储结构紧凑,字段少时非常节省内存。
每个 Hash 最多可包含:995,701,749 个字段。
| 命令 | 描述 |
| HDEL key field1 [field2] | 删除一个或多个哈希表字段 |
| HEXISTS key field | 查看哈希表 key 中,指定的字段是否存在。 |
| HGET key field | 获取存储在哈希表中指定字段的值。 |
| HGETALL key | 获取在哈希表中指定 key 的所有字段和值 |
| HINCRBY key field increment | 为哈希表 key 中的指定字段的整数值加上增量 increment 。 |
| HINCRBYFLOAT key field increment | 为哈希表 key 中的指定字段的浮点数值加上增量 increment 。 |
| HKEYS key | 获取所有哈希表中的字段 |
| HLEN key | 获取哈希表中字段的数量 |
| HMGET key field1 [field2] | 获取所有给定字段的值 |
| HMSET key field1 value1 [field2 value2 ] | 同时将多个 field-value (域-值)对设置到哈希表 key 中。 |
| HSET key field value | 将哈希表 key 中的字段 field 的值设为 value 。 |
| HSETNX key field value | 只有在字段 field 不存在时,设置哈希表字段的值。 |
| HVALS key | 获取哈希表中所有值 |
| HSCAN key cursor [MATCH pattern] [COUNT count] | 迭代哈希表中的键值对。 |
1.HSET语法
HSET hash field value
将哈希表 hash 中域 field 的值设置为 value 。
如果给定的哈希表并不存在, 那么一个新的哈希表将被创建并执行 HSET 操作。
如果域 field 已经存在于哈希表中, 那么它的旧值将被新值 value 覆盖。
2.代码示例
设置一个新域:
redis> HSET website google "www.g.cn"
(integer) 1
redis> HGET website google
"www.g.cn"
对一个已存在的域进行更新:
redis> HSET website google "www.google.com"
(integer) 0
redis> HGET website google
"www.google.com"
2.HSETNX
1.语法
HSETNX hash field value
当且仅当域 field 尚未存在于哈希表的情况下, 将它的值设置为 value 。
如果给定域已经存在于哈希表当中, 那么命令将放弃执行设置操作。
如果哈希表 hash 不存在, 那么一个新的哈希表将被创建并执行 HSETNX 命令。
返回值:
HSETNX 命令在设置成功时返回1,在给定域已经存在而放弃执行设置操作时返回0.
2.代码示例
域尚未存在, 设置成功:
redis> HSETNX database key-value-store Redis
(integer) 1
redis> HGET database key-value-store
"Redis"
域已经存在, 设置未成功, 域原有的值未被改变:
redis> HSETNX database key-value-store Riak
(integer) 0
redis> HGET database key-value-store
"Redis"
3.HGET
1.语法
HGET hash field
返回哈希表中给定域的值
返回值:
HGET 命令在默认情况下返回给定域的值。
如果给定域不存在于哈希表中,又或者给定的哈希表并不存在,那么命令返回 nil 。
2.代码示例
域存在的情况:
redis> HSET homepage redis redis.com
(integer) 1
redis> HGET homepage redis
"redis.com"
域不存在的情况:
redis> HGET site mysql
(nil)
6.Redis LIST(列表)
1.LIST 介绍
List类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样,我们可以在其头部(left)和尾部(right)添加新的元素。
在插入时,如果该键并不存在,Redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。
List中可以包含的最大元素数量是4294967295。
| 命令 | 描述 |
| BLPOP key1 [key2 ] timeout | 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
| BRPOP key1 [key2 ] timeout | 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
| BRPOPLPUSH source destination timeout | 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
| LINDEX key index | 通过索引获取列表中的元素 |
| LINSERT key BEFORE|AFTER pivot value | 在列表的元素前或者后插入元素 |
| LLEN key | 获取列表长度 |
| LPOP key | 移出并获取列表的第一个元素 |
| LPUSH key value1 [value2] | 将一个或多个值插入到列表头部 |
| LPUSHX key value | 将一个值插入到已存在的列表头部 |
| LRANGE key start stop | 获取列表指定范围内的元素 |
| LREM key count value | 移除列表元素 |
| LSET key index value | 通过索引设置列表元素的值 |
| LTRIM key start stop | 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。 |
| RPOP key | 移除并获取列表最后一个元素 |
| RPOPLPUSH source destination | 移除列表的最后一个元素,并将该元素添加到另一个列表并返回 |
| RPUSH key value1 [value2] | 在列表中添加一个或多个值 |
| RPUSHX key value | 为已存在的列表添加值 |
2.LIST 应用场景
消息队列系统,比如sina微博
在Redis中我们的最新微博ID使用了常驻缓存,这是一直更新的。但是做了限制不能超过5000个ID,因此获取ID的函数会一直询问Redis。只有在start/count参数超出了这个范围的时候,才需要去访问数据库。
系统不会像传统方式那样“刷新”缓存,Redis实例中的信息永远是一致的。SQL数据库(或是硬盘上的其他类型数据库)只是在用户需要获取“很远”的数据时才会被触发,而主页或第一个评论页是不会麻烦到硬盘上的数据库了。
3.LIST 操作介绍
1.LPUSH
1.语法
LPUSH key value [value …]
将一个或多个值 value 插入到列表 key 的表头
如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表头: 比如说,对空列表 mylist 执行命令 LPUSH mylist a b c ,列表的值将是 c b a ,这等同于原子性地执行 LPUSH mylist a 、 LPUSH mylist b 和 LPUSH mylist c 三个命令。
如果 key 不存在,一个空列表会被创建并执行 LPUSH 操作。
当 key 存在但不是列表类型时,返回一个错误。
返回值:
执行 LPUSH 命令后,列表的长度。
2.代码示例
# 加入单个元素
redis> LPUSH languages python
(integer) 1
# 加入重复元素
redis> LPUSH languages python
(integer) 2
redis> LRANGE languages 0 -1 # 列表允许重复元素
1) "python"
2) "python"
# 加入多个元素
redis> LPUSH mylist a b c
(integer) 3
redis> LRANGE mylist 0 -1
1) "c"
2) "b"
3) "a"
7.Redis SET(集合)
1.SET 介绍
Set类型看作为没有排序的字符集合。Set可包含的最大元素数量是4294967295。如果多次添加相同元素,Set中将仅保留该元素的一份拷贝。
| 命令 | 描述 |
| SADD key member1 [member2] | 向集合添加一个或多个成员 |
| SCARD key | 获取集合的成员数 |
| SDIFF key1 [key2] | 返回给定所有集合的差集 |
| SDIFFSTORE destination key1 [key2] | 返回给定所有集合的差集并存储在 destination 中 |
| SINTER key1 [key2] | 返回给定所有集合的交集 |
| SINTERSTORE destination key1 [key2] | 返回给定所有集合的交集并存储在 destination 中 |
| SISMEMBER key member | 判断 member 元素是否是集合 key 的成员 |
| SMEMBERS key | 返回集合中的所有成员 |
| SMOVE source destination member | 将 member 元素从 source 集合移动到 destination 集合 |
| SPOP key | 移除并返回集合中的一个随机元素 |
| SRANDMEMBER key [count] | 返回集合中一个或多个随机数 |
| SREM key member1 [member2] | 移除集合中一个或多个成员 |
| SUNION key1 [key2] | 返回所有给定集合的并集 |
| SUNIONSTORE destination key1 [key2] | 所有给定集合的并集存储在 destination 集合中 |
| SSCAN key cursor [MATCH pattern] [COUNT count] | 迭代集合中的元素 |
2.SET 应用场景
在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。
Redis还为集合提供了求交集、并集、差集等操作,可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。
3.SET 操作介绍
1.SADD
1.语法
SADD key member [member …]
将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
假如 key 不存在,则创建一个只包含 member 元素作成员的集合。
当 key 不是集合类型时,返回一个错误。
返回值:
被添加到集合中的新元素的数量,不包括被忽略的元素。
2.代码示例
# 添加单个元素
redis> SADD bbs "discuz.net"
(integer) 1
# 添加重复元素
redis> SADD bbs "discuz.net"
(integer) 0
# 添加多个元素
redis> SADD bbs "tianya.cn" "groups.google.com"
(integer) 2
redis> SMEMBERS bbs
1) "discuz.net"
2) "groups.google.com"
3) "tianya.cn"
8.Redis SortedSet(有序集合)
1.SortedSet 介绍
Sorted-Sets中的每一个成员都会有一个分数(score)与之关联,Redis正是通过分数来为集合中的成员进行从小到大的排序。成员是唯一的,但是分数(score)却是可以重复的。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
| 命令 | 描述 |
| ZADD key score1 member1 [score2 member2] | 向有序集合添加一个或多个成员,或者更新已存在成员的分数 |
| ZCARD key | 获取有序集合的成员数 |
| ZCOUNT key min max | 计算在有序集合中指定区间分数的成员数 |
| ZINCRBY key increment member | 有序集合中对指定成员的分数加上增量 increment |
| ZINTERSTORE destination numkeys key [key ...] | 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中 |
| ZLEXCOUNT key min max | 在有序集合中计算指定字典区间内成员数量 |
| ZRANGE key start stop [WITHSCORES] | 通过索引区间返回有序集合成指定区间内的成员 |
| ZRANGEBYLEX key min max [LIMIT offset count] | 通过字典区间返回有序集合的成员 |
| ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] | 通过分数返回有序集合指定区间内的成员 |
| ZRANK key member | 返回有序集合中指定成员的索引 |
| ZREM key member [member ...] | 移除有序集合中的一个或多个成员 |
| ZREMRANGEBYLEX key min max | 移除有序集合中给定的字典区间的所有成员 |
| ZREMRANGEBYRANK key start stop | 移除有序集合中给定的排名区间的所有成员 |
| ZREMRANGEBYSCORE key min max | 移除有序集合中给定的分数区间的所有成员 |
| ZREVRANGE key start stop [WITHSCORES] | 返回有序集中指定区间内的成员,通过索引,分数从高到底 |
| ZREVRANGEBYSCORE key max min [WITHSCORES] | 返回有序集中指定分数区间内的成员,分数从高到低排序 |
| ZREVRANK key member | 返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序 |
| ZSCORE key member | 返回有序集中,成员的分数值 |
| ZUNIONSTORE destination numkeys key [key ...] | 计算给定的一个或多个有序集的并集,并存储在新的 key 中 |
| ZSCAN key cursor [MATCH pattern] [COUNT count] | 迭代有序集合中的元素(包括元素成员和元素分值) |
2.SortedSet 应用场景
排行榜应用,取TOP N操作这个需求与上面需求的不同之处在于,前面操作以时间为权重,这个是以某个条件为权重,比如按顶的次数排序,这时候就需要我们的sorted set出马了,将你要排序的值设置成sorted set的score,将具体的数据设置成相应的value,每次只需要执行一条ZADD命令即可。
3.SortedSet 操作介绍
1.ZADD
1.语法
ZADD key score member [[score member] [score member] …]
将一个或多个 member 元素及其 score 值加入到有序集 key 当中。
如果某个 member 已经是有序集的成员,那么更新这个 member 的 score 值,并通过重新插入这个 member 元素,来保证该 member 在正确的位置上。
score 值可以是整数值或双精度浮点数。
如果 key 不存在,则创建一个空的有序集并执行 ZADD 操作。
当 key 存在但不是有序集类型时,返回一个错误。
对有序集的更多介绍请参见 sorted set 。
返回值:
被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员。
2.代码示例
# 添加单个元素
redis> ZADD page_rank 10 google.com
(integer) 1
# 添加多个元素
redis> ZADD page_rank 9 baidu.com 8 bing.com
(integer) 2
redis> ZRANGE page_rank 0 -1 WITHSCORES
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"
# 添加已存在元素,且 score 值不变
redis> ZADD page_rank 10 google.com
(integer) 0
redis> ZRANGE page_rank 0 -1 WITHSCORES # 没有改变
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"
# 添加已存在元素,但是改变 score 值
redis> ZADD page_rank 6 bing.com
(integer) 0
redis> ZRANGE page_rank 0 -1 WITHSCORES # bing.com 元素的 score 值被改变
1) "bing.com"
2) "6"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"
3.Redis集群
1.Python链接Redis
1.安装Python以及Redis模块
yum -y install python3 python3-pip
mkdir ~/.pip
vim ~/.pip/pip.conf
[global]
index-url=http://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host=mirrors.aliyun.com
pip3 install redis
2.如何链接
#注意要关闭redis的保护模式 protected-mode no
In [1]: import redis
In [2]: r = redis.Redis(host='192.168.9.150', port=6379)
In [3]: r.set("leokon", "www.leokonlab.cn")
Out[3]: True
In [4]: r.get("leokon")
Out[4]: b'www.leokonlab.com'
In [5]: ret = r.get("leokon")
In [6]: ret.decode()
Out[6]: 'www.leokonlab.com'
3.连接池
redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销
默认,每个Redis实例都会维护一个自己的连接池
可以直接建立一个连接池,然后作为参数传给Redis,这样就可以实现多个 Redis 实例共享一个连接池
In [12]: pool = redis.ConnectionPool(host='192.168.9.150', port=6379)
In [13]: rs = redis.Redis(connection_pool=pool)
In [14]: rs.set("foo", "bar")
Out[14]: True
In [15]: rs.get("foo")
Out[15]: b'bar'
4.Redis缓存雪崩/穿透/击穿
1.缓存雪崩
1.案例
假设系统 A 在高峰期每秒有 5000 个请求,而 Redis 缓存本可承载其中的 4000 个。某天缓存服务器突然全盘宕机,所有请求直达数据库,导致数据库瞬间崩溃。数据库即使重启,也会立刻被新请求打挂,形成恶性循环,这就是缓存雪崩。

2.解决方案
缓存雪崩的事前事中事后的解决方案如下:
事前防范:
- 部署 Redis 高可用架构(如主从 + Sentinel 或 Redis Cluster),避免单点故障;
- 为缓存设置合理的过期时间并加上随机因子,避免大量 key 同时过期。
事中缓冲:
- 使用本地缓存(如 EhCache)作为第一层防线;
- 配合 Hystrix 实现限流与降级,控制访问速率,防止数据库被压垮。
事后恢复:
- 启用 Redis 持久化机制(RDB 或 AOF),确保重启后快速恢复数据,缩短不可用时间。
注意:
- EhCache 是一个轻量级的 Java 本地缓存框架,访问速度快;
- Hystrix 是 Netflix 开源的容错框架,可实现线程隔离、限流、降级等。

用户发送一个请求,系统 A 收到请求后,先查本地 ehcache 缓存,如果没查到再查 redis。如果 ehcache 和 redis 都没有,再查数据库,将数据库中的结果,写入 ehcache 和 redis 中。
限流组件,可以设置每秒的请求,有多少能通过组件,剩余的未通过的请求,怎么办?走降级!可以返回一些默认的值,或者友情提示,或者空白的值。
3.好处
数据库绝对不会死,限流组件确保了每秒只有多少个请求能通过。
只要数据库不死,就是说,对用户来说,2/5 的请求都是可以被处理的。
只要有 2/5 的请求可以被处理,就意味着你的系统没死,对用户来说,可能就是点击几次刷不出来页面,但是多点几次,就可以刷出来一次。
2.缓存穿透
1.案例
黑客对系统 A 发起大量恶意请求,请求的 key 为数据库中根本不存在的数据(如负数 ID)。由于缓存中没有这些 key,每次都绕过缓存直达数据库,最终导致数据库压力骤增甚至崩溃。

2.解决方案
- 对于数据库中查不到的数据,也将其结果(如
null或特殊标记)缓存起来,并设置合理过期时间。例如:
SET -999 "UNKNOWN" EX 60 - 配合布隆过滤器拦截非法 key,提高效率。
3.缓存击穿
1.案例
某些 key 是热点数据,访问频繁。如果这些 key 在某一刻刚好过期,在短时间内大量请求同时落在数据库上,导致数据库压力激增,这就是缓存击穿。
2.解决方案
- 对热点数据设置永不过期;
- 或在缓存失效前,使用互斥锁机制(基于 Redis 或 ZooKeeper)保证只有一个请求去加载数据,其它请求等待或返回旧数据,等缓存重建完成后再恢复访问。
#后续恢复更新~~
更多推荐
所有评论(0)