Skip to content

简介

简介

Redis 是 REmote DIctionary Server(远程字典服务器)的缩写,它以字典结构存储数据,并允许其他应用通过 TCP 协议读写字典中的内容

https://redis.io/

https://github.com/redis/redis

http://www.redis.cn/

Redis 除了变得越来越受欢迎之外,另一个变化就是更新越来越快,功能也变得越来越多、越来越强大,
比如说,Redis 的数据结构数量已经从过去的五种增加到了九种,RDB-AOF 混合持久化模式的引入使得用户不必再陷入“鱼和熊掌不可兼得”的难题中,
而集群功能和模块机制的引入则让 Redis 在性能和功能上拥有近乎无限的扩展能力

Redis 是一个主要由 Salvatore Sanfilippo(Antirez)开发的开源内存数据结构存储器,经常用作数据库、缓存以及消息代理等。

Redis 因其丰富的数据结构、极快的速度、齐全的功能而为人所知,它是目前内存数据库方面的事实标准,在互联网上非常广泛的应用,微博,Tritter、GitHub、Stack Overflow、知乎等国内外公司都大量使用了 Redis。

Redis 之所以广受开发者欢迎,跟它自身拥有强大的功能以及简洁的设计不无关系。

Redis 最重要的特点有以下几种:

Redis特点

安装

安装 redis-6.2.4 示例:

1
2
3
4
$ wget https://download.redis.io/releases/redis-6.2.4.tar.gz
$ tar xzf redis-6.2.4.tar.gz
$ cd redis-6.2.4
$ make

然后在~/.zshrc中添加如下内容:

1
export PATH="/root/redis-6.2.4/src:$PATH"
1
2
3
$ source ~/.zshrc
$ redis-cli --version
redis-cli 6.2.4

此时默认配置为: /root/redis-6.2.4/redis.conf,可以将其复制到其他路径修改使用

使用 conda 安装

如果用 anaconda 安装的 python

可以直接执行:

1
conda install redis

然后下载完成后就可以使用 redis 了,但是版本可能不是最新稳定版的

1
2
$ redis-cli --version
redis-cli 5.0.3

centos 安装

http://rpms.remirepo.net/enterprise/

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
yum install epel-release -y
yum install -y http://rpms.remirepo.net/enterprise/remi-release-7.rpm

yum --enablerepo=remi install redis -y
# Warning: redis configuration is now in /etc/redis directory

#   清理        : redis-3.2.12-2.el7.x86_64                                                    2/2
# warning: file /etc/redis.conf: remove failed: No such file or directory
# warning: file /etc/redis-sentinel.conf: remove failed: No such file or directory
ls /usr/bin/redis*
# /usr/bin/redis-benchmark  /usr/bin/redis-check-rdb  /usr/bin/redis-sentinel
# /usr/bin/redis-check-aof  /usr/bin/redis-cli        /usr/bin/redis-server

在 .zshrc 添加如下内容:

1
export PATH=$PATH:/usr/bin

source ~/.zshrc

1
2
redis-cli --version
# redis-cli 7.2.4

特性

(1) 存储结构

Redis 支持的键值数据类型:字符串类型、散列类型、列表类型、集合类型和有序集合类型

Redis 为用户提供了字符串、散列、列表、集合、有序集合、HyperLogLog、位图、流、地理坐标等一系列丰富的数据结构,每种数据结构都适用于解决特定的问题。
在有需要的时候,用户还可以通过事务、Lua 脚本、模块等特性,扩展已有数据结构的功能,甚至从零实现自己专属的数据结构。
通过这些数据结构和特定,Redis 能够确保用户可以使用适合的工具去解决问题

(2) 内存存储与持久化

Redis 数据库中的所有数据都存储在内存中。由于内存的读写速度远快于硬盘,因此 Redis 在性能上对比其他基于硬盘存储的数据库有非常明显的优势,在一台普通的笔记本电脑上,Redis 可以在一秒内读写超过十万个键值

将数据存储在内存中也有问题,例如,程序退出后内存中的数据丢失。不过 Redis 提供了对持久化的支持,即可以将内存中的数据异步写入到硬盘中,同时不影响继续提供服务

(3) 功能丰富

Redis 虽然是作为数据库开发的,但由于其提供了丰富的功能,越来越多的人将其用作缓存、队列系统等。

Redis 可以为每个键设置生存时间(Time To Live, TTL),生存时间到期后键会自动被删除。这一功能配合出色的性能让 Redis 可以作为缓存系统来使用

Redis 的列表类型键可以用来实现队列,并且支持阻塞式读取,可以很容易地实现一个高性能的优先级队列。

Redis 提供了很多非常实用的附加功能,比如自动过期、流水线、事务、数据持久化等,这些功能能够帮助用户将 Redis 应用在更多不同的场景中,或者为用户带来便利。
更重要的是,Redis 不仅可以单机使用,还可以多机使用:通过 Redis 自带的复制、Sentinel 和集群功能,用户可以将自己的数据库扩展至任意大小。
无论你运营的是一个小型的个人网站,还是一个为上千万消费者服务的热门站点,都可以在 Redis 中找到你想要的功能,并将其部署到你的服务器中

(4) 速度飞快

Redis 是一款内存数据库,它将素有数据存储在内存中。
因为计算机访问内存的速度要远远高于访问硬盘的速度,所以与基于硬盘设计的传统数据库相比,Redis 在数据的存取速度方面具有天然的优势。
但 Redis 并没有因此放弃在效率放面的追求,相反,Redis 的开发者在实现各项数据结构和特性的时候都经过了大量考量,在底层选用了很多非常高效的数据结构和算法,以此来确保每个操作都可以在尽可能短的时间内完成,并且尽可能地节省内存。

(5) 简单稳定

在 Redis 中使用命令来读写数据,命令语句之于 Redis 就相当于 SQL 语言之于关系数据库

Redis 是开源的,使用 C 语言开发,代码量只有 3 万多行。这降低了用户通过修改 Redis 源代码来使之更适合自己项目需要的门槛

(6) 支持广泛

Redis 已经在互联网公司得到广泛应用,许多开发者为不同的编程语言开发了相应的客户端(redis.io/clients),
大多数编程语言的使用者都可以轻而易举地找到所需的客户端,然后直接开始使用 Redis。
此外,包括亚马逊、谷歌、RedisLabs、阿里云和腾讯云在内的多个云服务提供商都提供了基于 Redis 或兼容 Redis 的服务,如果你不打算自己搭建 Redis 服务器,那么上述提供商可能是不错的选择。

启动和停止 Redis

直接启动:运行redis-server,Redis 服务器默认使用 6379 端口,通过 --port 参数可以自定义端口号

停止 Redis: 考虑到 Redis 有可能正在将内存中的数据同步到硬盘中,强行终止 Redis 进程可能会导致数据丢失。正确停止 Redis 的方式应该是向 Redis 发送 SHUTDOWD 命令,方法为

redis-cli SHUTDOWN

当 Redis 收到 SHUTDOWN 命令后,会先断开所有客户端连接,然后根据配置执行持久化,最后完成退出

命令行使用

1
2
3
$ redis-cli
127.0.0.1:6379> PING
PONG

Python 中使用 redis

1
In [1]: from redis import Redis
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import json
from redis import StrictRedis

# for db in range(2):
#     redis = StrictRedis(host="0.0.0.0", port=6381, db=db)
#     redis.flushdb()

redis = StrictRedis(host="0.0.0.0", port=6380, db=1)

def du(data):
    return json.dumps(data, ensure_ascii=False).encode()

for i in itr:
    redis.hset("lalala", du(i['code']), du(i['vol']))

redis url

使用数据库 1:redis://127.0.0.1:6379/1

配置文件 redis.conf

Mac 下所在目录:/usr/local/etc/redis.conf

5.0 版本默认配置文件:https://github.com/antirez/redis/blob/5.0/redis.conf

启动redis服务指定配置文件:redis-server redis.conf

执行命令

Redis 服务器通过接收客户端发送的命令请求来执行指定的命令,并在命令执行完毕之后通过响应将命令的执行结果返回给客户端,结果中的内容称为命令回复。

Redis 为每种数据结构和功能特性都提供了相应的命令,掌握如何使用这些命令是学习 Redis 的重中之重。
幸运的是,大部分 Redis 命令都非常简单,只需要给出少量参数就可以完成非常强大的操作。

Redis 的所有命令都由一个命令名后跟任意多个参数以及可选项组成:

1
COMMAND [arg1 arg2 arg3 ...] [[OPTION1 value1] [OPTION2 value2] [...]]

命令和可选项的名字通常以大写字母形式出现,命令参数和可选项的值则以小写字母形式出现。
比如上例中的 COMMAND 就是命令的名字,OPTION1 和 OPTION2 是可选项的名字,arg1、arg2 和 arg3 是命令的参数,value1 和 value2 是可选项的值

命令描述中的方括号[]仅用于包围命令中可选的参数和选项,在执行命令的时候并不需要给出这些方括号。
命令描述中的...用于表示命令接受任意数量的参数或可选项

现在让我们来看一个实际的例子。
Redis 的 PING 命令接受一条可选的消息作为参数,这个命令通常用于测试客户端和服务器之间的连接是否正常:

1
PING [message]

如果用户以无参数形式执行这个命令,那么服务器在连接正常的情况下,将向客户端返回 PONG 作为回复:

1
2
3
➜  ~ redis-cli
127.0.0.1:6379> PING
PONG

但是,如果用户给定了可选的消息,那么服务器将原封不动地向客户端返回该消息:

1
2
127.0.0.1:6379> PING "hello world"
"hello world"

另外,如果服务器与客户端连接不正常,那么客户端将返回一个错误:

1
2
3
4
➜  ~ redis-cli
Could not connect to Redis at 127.0.0.1:6379: Connection refused
not connected> PING
Could not connect to Redis at 127.0.0.1:6379: Connection refused

配置服务器

有时候我们还需要使用配置选项对 Redis 服务器进行配置,这可以通过两种方法来完成。

第一种方法是在启动 Redis 服务器的时候给定配置选项作为参数,格式为:

1
redis-server --OPTION1 [value1 value2 ...] --OPTION2 [value1 value2 ...] [...]

例如,Redis 服务器默认使用 6379 作为端口号,但如果你想使用 10086 而不是 6379 作为端口号,那么可以在启动 Redis 服务器时通过设定 port 可选项来指定想要的端口号:

1
redis-server --port 10086

第二种方法是在启动 Redis 服务器的时候为其提供配置文件,并将想要修改的配置选项写在配置文件中

1
redis-server /path/to/your/file

例如,为了将 Redis 服务器的端口号改为 12345,我们可以在当前文件夹中创建配置文件 myredis.conf,并在文件中包含以下内容:

1
port 12345

然后在启动 Redis 服务器时向其提供配置文件:

redis-server myredis.conf

如果需要启动 redis 时直接在后台以守护进程方式运行,可以进行如下配置:

1
daemonize yes

示例代码

检查连接的脚本:

1
2
3
4
5
6
7
8
from redis import Redis

client = Redis()

if client.ping():
    print("connecting")
else:
    print("disconnected")

docker 启动 redis

1
2
docker pull redis
docker run -d -p 6379:6379 redis

停止redis:

1
2
3
4
5
6
7
➜  ~ docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                    NAMES
93e9c2300c90   redis     "docker-entrypoint.s…"   27 seconds ago   Up 25 seconds   0.0.0.0:6379->6379/tcp   busy_bartik
➜  ~ docker stop 93e
93e
➜  ~ docker rm 93e
93e
1
docker run -d -p 6390:6379 redis

使用密码连接

1
2
3
4
5
from redis import StrictRedis

redis = StrictRedis(host="127.0.0.1", port=6379, password="xxx")

print(redis.keys())

Redis 使用场景

Redis 可以做什么

缓存:
缓存机制几乎在所有的大型网站都有使用,合理地使用缓存不仅可以加快数据的访问速度,而且能够有效地降低后端数据源的压力。
Redis 提供了键值过期时间设置,并且也提供了灵活控制最大内存和内存溢出后的淘汰策略。

排行榜系统
排行榜系统几乎存在于所有的网站,例如按照热度排名的排行榜,按照发布时间的排行榜,按照各种复杂维度计算出的排行榜,Redis 提供了列表和有序集合数据结构,合理地使用这些数据结构可以很方便地构建各种排行榜系统

计数器应用

计数器在网站中的作用至关重要,例如视频有播放数、电商网站有浏览数,为了保证数据的实时性,每一次播放和浏览都要做加 1 的操作,如果并发量很大对于传统关系型数据的性能是一种挑战。
Redis 天然支持计数功能而且计数的性能也非常好,可以说是计数器系统的重要选择

社交网络

赞/踩、粉丝、共同好友/喜好、推送、下拉刷新等是社交网站的必备功能,由于社交网站访问量通常比较大,而且传统的关系型数据不太适合保存这种类型的数据,Redis 提供的数据结构可以相对比较容易地实现这些功能

消息队列系统

消息队列系统可以说是一个大型网站的必备基础组件,因为其具有业务解耦、非实时业务削峰等特性。
Redis 提供了发布订阅功能和阻塞队列的功能,虽然和专业的消息队列比还不够强大,但是对于一般的消息队列功能基本可以满足

Redis不可以做什么

实际上和任何一门技术一样,每个技术都有自己的应用场景和边界,也就是说 Redis 并不是万金油,有很多适合它解决的问题,但是也有很多不合适它解决的问题。我们可以站在数据规模和数据冷热的角度来进行分析

站在数据规模的角度看,数据可以分为大规模数据和小规模数据,我们知道 Redis 的数据是存放在内存中的,虽然现在内存已经足够便宜,淡水如果数据量非常大,例如每天有几亿的用户行为数据,使用 Redis 来存储的话,基本上是个无底洞,经济成本相当的高

站在数据冷热的角度看,数据分为热数据和冷数据,热数据通常是指需要频繁操作的数据,反之为冷数据,例如对于视频网站来说,视频基本信息基本上在各个业务线都是经常要操作的数据,而用户的观看记录不一定是经常需要访问的数据,这里暂且不讨论两者数据规模的差异,单纯站在数据冷热的角度上看,视频信息属于热数据,用户观看记录属于冷数据。
如果将这些冷数据放在 Redis 中,基本上是对于内存的一种浪费,但是对于一些热数据可以放在 Redis 中加速读写,也可以减轻后端存储的负载,可以说是事半功倍。

所以,Redis 并不是万金油。

用好 Redis 的建议

切勿当作黑盒使用,开发与运维同样重要

很多使用 Redis 的开发者认为只要会用 API 开发相应的功能就可以,更有甚者认为 Redis 就是 get、set、del,不需要知道 Redis 的原理。
但是在我们实际运维和使用 Redis 的过程中发现,很多线上的故障和问题都是由于完全把 Redis 当作黑盒造成的,如果不了解 Redis 的单线程模型,有些开发者会在有成千上万个键的 Redis 上执行 keys* 操作,如果不了解持久化的相关原理,会在一个写操作量很大的 Redis 上配置自动保存 RDB。
而且在很多公司内只有专职的关系型数据库 DBA,并没有 NoSQL 的相关运维人员,也就是说开发者很有可能会自己运维 Redis,对于 Redis 的开发者来说即是好事又是坏事。
站在好的方面看,开发人员可以通过运维 Redis 真正了解 Redis 的一些原理,不单纯停留在开发上。
站在坏的方面看,Redis 开发人员不仅要支持开发,还要承担运维的责任,而且由于运维经验不足可能会造成线上故障。
但是从实际经验来看,运维足够规模的 Redis 会对用好 Redis 更加有帮助

阅读源码

客户端

推荐几款 Redis 可视化工具

RDM

Redis Desktop Manager(rdm): 收费,需破解

Redis Insight

https://redislabs.com/redisinsight/

redis labs出的一款监控分析级别的redis可视化工具。这款软件是web版的。

AnotherRedisDesktopManager

https://github.com/qishibo/AnotherRedisDesktopManager

Medis

http://getmedis.com/