教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 Redis基础教程

Redis基础教程

发布时间:2022-02-08   编辑:jiaochengji.com
教程集为您提供Redis基础教程等资源,欢迎您收藏本站,我们将为您提供最新的Redis基础教程资源
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"/></svg>

微信公众号:编程笔记本

<blockquote>

点击上方蓝字关注我,我们一起学编程
如果觉得内容还不错,请帮忙分享一下
有任何疑问或者想看的内容,欢迎私信

</blockquote>

今天我们来学习一下 Redis 的使用。

<h3>目录</h3>

<h3>文章目录</h3> <ul><li><ul><li><ul><li>目录</li><li>介绍</li><li>安装</li><li>配置</li><li>数据类型</li><li>命令</li><li>键</li><li>字符串</li><li>哈希</li><li>列表</li><li>集合</li><li>有序集合</li><li>HyperLogLog</li><li>发布订阅</li><li>事务</li><li>脚本</li><li>连接</li><li>服务器</li><li>数据备份与恢复</li><li>安全</li><li>性能测试</li><li>客户端连接</li><li>管道技术</li><li>分区</li></ul></li></ul></li></ul>

<h3>介绍</h3>

Redis 是完全开源免费的,遵守 BSD 协议,是一个高性能的 key-value 数据库

Redis 与其他 key - value 缓存产品有以下三个特点:

<ul><li>Redis 支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。</li><li>Redis 不仅仅支持简单的 key-value 类型的数据,同时还提供 list、set、zset、hash 等数据结构的存储。</li><li>Redis 支持数据的备份,即 master-slave 模式的数据备份。</li></ul>

优势

<ul><li>性能极高:Redis 能读的速度是 110000 次每秒,写的速度是 81000 次每秒。</li><li>丰富的数据类型:Redis 支持二进制案例的 Strings、Lists、Hashes、Sets 及 Ordered Sets 数据类型操作。</li><li>原子:Redis 的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过 MULTI 和 EXEC 指令包起来。</li><li>丰富的特性:Redis 还支持 publish/subscribe、通知、key 过期等等特性。</li></ul>

区别

Redis 与其他 key-value 存储有什么不同呢?

<ul><li>Redis 有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis 的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。</li><li>Redis 运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样 Redis 可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。</li></ul><h3>
安装</h3>

因为笔者的主机是 linux 系统,因此我们只介绍 linux 环境下的安装方式。

<pre><code>wget http://download.redis.io/releases/redis-5.0.8.tar.gz tar xzf redis-5.0.8.tar.gz cd redis-5.0.8/ make </code></pre>

由于 Redis 是开源软件,所以我们可以选择在线安装。第一句是下载源码,第二句是解压,后面三句是进入安装目录并执行安装。这也是 linux 环境下,大部分软件安装的流程和方式。

安装完成后,我们需要添加环境变量,以便于在任何位置启动 redis 。

<pre><code># 切换到root用户,修改/etc/profile文件,添加: export PATH=$PATH:<redis-server和redis-cli所在目录> </code></pre>

启动 redis 服务器:

<pre><code>jincheng@jincheng:~$ redis-server 2492:C 13 Apr 2020 14:55:23.175 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 2492:C 13 Apr 2020 14:55:23.175 # Redis version=5.0.8, bits=64, commit=00000000, modified=0, pid=2492, just started 2492:C 13 Apr 2020 14:55:23.175 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf 2492:M 13 Apr 2020 14:55:23.176 * Increased maximum number of open files to 10032 (it was originally set to 1024). _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 5.0.8 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 2492 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 2492:M 13 Apr 2020 14:55:23.178 # Server initialized 2492:M 13 Apr 2020 14:55:23.178 # 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. 2492:M 13 Apr 2020 14:55:23.178 # 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. 2492:M 13 Apr 2020 14:55:23.178 * Ready to accept connections </code></pre>

启动 redis 命令行客户端:

<pre><code>jincheng@jincheng:~$ redis-cli 127.0.0.1:6379> ping PONG 127.0.0.1:6379> </code></pre>

可以看到,服务器已响应。其中,127.0.0.1 是本机 IP ,6379 是 redis 默认的服务端口。

<h3>
配置</h3>

Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf 。

详细的配置说明如下:

图片-1

以特定配置文件启动 redis 服务:

<pre><code>jincheng@jincheng:~$ redis-server /home/jincheng/SoftWare/redis-5.0.8/redis.conf </code></pre> <h3>
数据类型</h3>

Redis 支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及 zset(sorted set:有序集合)。

具体如下表所示:

图片-2

String(字符串)

string 是 redis 最基本的类型,可以理解为与 Memcached 一模一样的类型,一个 key 对应一个 value 。string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如 jpg 图片或者序列化的对象。string 类型的值最大能存储 512MB 。

<pre><code class="lang-bash hljs">jincheng@jincheng:~$ redis-cli 127.0.0.1:6379<span class="token operator">></span> SET jincheng <span class="token string">"ok"</span> OK 127.0.0.1:6379<span class="token operator">></span> get jincheng <span class="token string">"ok"</span> 127.0.0.1:6379<span class="token operator">></span> </code></pre>

redis 中的命令不区分大小写。在以上实例中我们使用了 SET 和 GET 命令。键为 jincheng,对应的值为 ok 。

注意:一个键最大能存储 512MB。

Hash(哈希)

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

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> hmset person name <span class="token string">"jincheng"</span> age <span class="token string">"18"</span> sex <span class="token string">"male"</span> OK 127.0.0.1:6379<span class="token operator">></span> hget person name <span class="token string">"jincheng"</span> 127.0.0.1:6379<span class="token operator">></span> hget person age <span class="token string">"18"</span> 127.0.0.1:6379<span class="token operator">></span> hget person sex <span class="token string">"male"</span> 127.0.0.1:6379<span class="token operator">></span> </code></pre>

上述实例中我们使用了 HMSET, HGET 命令,HMSET 设置了三个 field=>value 对, HGET 获取对应 field 对应的 value。每个 hash 可以存储 2^32 -1 个键值对。

List(列表)

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

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> lpush phones nokia <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 1 127.0.0.1:6379<span class="token operator">></span> lpush phones huawei oppo vivo <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 4 127.0.0.1:6379<span class="token operator">></span> lrange phones 0 10 1<span class="token punctuation">)</span> <span class="token string">"vivo"</span> 2<span class="token punctuation">)</span> <span class="token string">"oppo"</span> 3<span class="token punctuation">)</span> <span class="token string">"huawei"</span> 4<span class="token punctuation">)</span> <span class="token string">"nokia"</span> 127.0.0.1:6379<span class="token operator">></span> </code></pre>

一个列表最多可存储 2^32 - 1 个元素。

Set(集合)

Redis 的 Set 是 string 类型的无序集合。集合是通过哈希表实现的,所以添加、删除、查找的复杂度都是 O(1)

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> sadd <span class="token function">date</span> <span class="token string">"today"</span> <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 1 127.0.0.1:6379<span class="token operator">></span> sadd <span class="token function">date</span> <span class="token string">"yesterday"</span> <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 1 127.0.0.1:6379<span class="token operator">></span> sadd <span class="token function">date</span> <span class="token string">"tomorrow"</span> <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 1 127.0.0.1:6379<span class="token operator">></span> sadd <span class="token function">date</span> <span class="token string">"today"</span> <span class="token string">"yesterday"</span> <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 0 127.0.0.1:6379<span class="token operator">></span> smembers <span class="token function">date</span> 1<span class="token punctuation">)</span> <span class="token string">"tomorrow"</span> 2<span class="token punctuation">)</span> <span class="token string">"yesterday"</span> 3<span class="token punctuation">)</span> <span class="token string">"today"</span> 127.0.0.1:6379<span class="token operator">></span> </code></pre>

sadd 命令:添加一个 string 元素到 key 对应的 set 集合中,成功返回 1,如果元素已经在集合中返回 0。

一个集合中最大的成员数为 2^32 - 1 个,且不保存重复的值。

zset(sorted set:有序集合)

Redis zset 和 set 一样也是 string 类型元素的集合,但不允许重复的成员。不同的是每个元素都会关联一个double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。zset 的成员是唯一的,但分数(score) 却可以重复。

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> zadd fruit 0 apple 0 banana <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 2 127.0.0.1:6379<span class="token operator">></span> zadd fruit 0 pear <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 1 127.0.0.1:6379<span class="token operator">></span> zadd fruit 1 apple <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 0 127.0.0.1:6379<span class="token operator">></span> zrangebyscore fruit 0 10000 1<span class="token punctuation">)</span> <span class="token string">"banana"</span> 2<span class="token punctuation">)</span> <span class="token string">"pear"</span> 3<span class="token punctuation">)</span> <span class="token string">"apple"</span> 127.0.0.1:6379<span class="token operator">></span> </code></pre>

zadd 命令:<code>zadd key score member</code> 添加元素到集合,元素在集合中存在则更新对应 score 。

<h3>
命令</h3>

Redis 命令用于在 redis 服务上执行操作。要在 redis 服务上执行命令需要一个 redis 客户端。

在本机上执行命令

在本机上执行 redis 命令,仅需在命令行中输入 redis-cli 即可:

<pre><code class="lang-bash hljs">jincheng@LAPTOP-E4NSNKIT:~$ redis-cli 127.0.0.1:6379<span class="token operator">></span> <span class="token function">ping</span> PONG 127.0.0.1:6379<span class="token operator">></span> </code></pre>

在远程服务上执行命令

此时我们需要登录远程主机的 redis 服务器,那么我们就需要知道服务器的 IP 地址、端口号、登陆密码。

由于默认的配置文件中配置的是不需要密码,所以我们先来创建密码:

<pre><code class="lang-bash hljs">jincheng@LAPTOP-E4NSNKIT:~$ redis-cli 127.0.0.1:6379<span class="token operator">></span> config <span class="token keyword">set</span> requirepass codingbook OK 127.0.0.1:6379<span class="token operator">></span> </code></pre>

上面的操作已经在 redis 上设置了密码:codingbook 。当我们再次登录时,若不提供密码,则 redis 服务器会提示需要认证:

<pre><code class="lang-bash hljs">jincheng@LAPTOP-E4NSNKIT:~$ redis-cli 127.0.0.1:6379<span class="token operator">></span> keys * <span class="token punctuation">(</span>error<span class="token punctuation">)</span> NOAUTH Authentication required. 127.0.0.1:6379<span class="token operator">></span> </code></pre>

所以,在 redis 设置了密码以后,我们在登陆上服务器之后,一定先进行认证:

<pre><code class="lang-bash hljs">jincheng@LAPTOP-E4NSNKIT:~$ redis-cli 127.0.0.1:6379<span class="token operator">></span> auth codingbook OK 127.0.0.1:6379<span class="token operator">></span> keys * <span class="token punctuation">(</span>empty list or set<span class="token punctuation">)</span> 127.0.0.1:6379<span class="token operator">></span> </code></pre>

有了密码以后,下面我们再来演示如何登陆远程 redis 服务器:

<pre><code class="lang-bash hljs">jincheng@LAPTOP-E4NSNKIT:~$ redis-cli -h 127.0.0.1 -p 6379 -a <span class="token string">"codingbook"</span> 127.0.0.1:6379<span class="token operator">></span> <span class="token function">ping</span> PONG 127.0.0.1:6379<span class="token operator">></span> </code></pre>

上面的命令表示:登录 IP 地址为 127.0.0.1 、端口号为 6379 、密码为 codingbook 的 redis 服务器。

<h3>
键</h3>

先看一个实例:

<pre><code class="lang-bash hljs">jincheng@LAPTOP-E4NSNKIT:~$ redis-cli 127.0.0.1:6379<span class="token operator">></span> SET tool redis OK 127.0.0.1:6379<span class="token operator">></span> DEL tool <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 1 127.0.0.1:6379<span class="token operator">></span> DEL tool <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 0 127.0.0.1:6379<span class="token operator">></span> </code></pre>

在上面的实例中,<code>DEL</code> 是一个命令,执行删除操作,<code>tool</code> 是一个键,如果键被删除成功,命令执行后输出 (integer) 1,否则将输出 (integer) 0 。

与键相关的命令

图-3

<h3>
字符串</h3>

先看一个实例:

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> SET name jincheng OK 127.0.0.1:6379<span class="token operator">></span> GET name <span class="token string">"jincheng"</span> 127.0.0.1:6379<span class="token operator">></span> </code></pre>

在以上实例中我们使用了 <code>SET</code> 和 <code>GET</code> 命令,键为 name。

与字符串相关的命令

图-4

<h3>
哈希</h3>

Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。Redis 中每个 hash 可以存储 2^32 - 1 个键值对。

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> HMSET person name <span class="token string">"jincheng"</span> age <span class="token string">"26"</span> school <span class="token string">"HFUT"</span> OK 127.0.0.1:6379<span class="token operator">></span> HGET person name <span class="token string">"jincheng"</span> 127.0.0.1:6379<span class="token operator">></span> HGETALL person 1<span class="token punctuation">)</span> <span class="token string">"name"</span> 2<span class="token punctuation">)</span> <span class="token string">"jincheng"</span> 3<span class="token punctuation">)</span> <span class="token string">"age"</span> 4<span class="token punctuation">)</span> <span class="token string">"26"</span> 5<span class="token punctuation">)</span> <span class="token string">"school"</span> 6<span class="token punctuation">)</span> <span class="token string">"HFUT"</span> 127.0.0.1:6379<span class="token operator">></span> </code></pre>

在以上实例中,我们设置了人的一些描述信息(name、age、school) 到哈希表 person 中。

与哈希相关的命令

图-5

<h3>
列表</h3>

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

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> LPUSH phone huawei <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 1 127.0.0.1:6379<span class="token operator">></span> LPUSH phone oppo vivo <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 3 127.0.0.1:6379<span class="token operator">></span> LRANGE phone 0 10 1<span class="token punctuation">)</span> <span class="token string">"vivo"</span> 2<span class="token punctuation">)</span> <span class="token string">"oppo"</span> 3<span class="token punctuation">)</span> <span class="token string">"huawei"</span> 127.0.0.1:6379<span class="token operator">></span> </code></pre>

在以上实例中我们使用了 <code>LPUSH</code> 将三个值插入了名为 phone 的列表当中。

与列表相关的命令

图-6

<h3>
集合</h3>

Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。Redis 中集合是通过哈希表实现的,所以添加、删除、查找的复杂度都是 O(1)。集合中最大的成员数为 2^32 - 1 。

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> SADD lang C C GO SQL <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 4 127.0.0.1:6379<span class="token operator">></span> SADD lang Python C <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 1 127.0.0.1:6379<span class="token operator">></span> SMEMBERS lang 1<span class="token punctuation">)</span> <span class="token string">"C "</span> 2<span class="token punctuation">)</span> <span class="token string">"SQL"</span> 3<span class="token punctuation">)</span> <span class="token string">"C"</span> 4<span class="token punctuation">)</span> <span class="token string">"GO"</span> 5<span class="token punctuation">)</span> <span class="token string">"Python"</span> 127.0.0.1:6379<span class="token operator">></span> </code></pre>

在以上实例中我们通过 <code>SADD</code> 命令向名为 lang 的集合插入若干个元素,重复元素只存储一份。

与集合相关的命令

图-7

<h3>
有序集合</h3>

Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。集合是通过哈希表实现的,所以添加、删除、查找的复杂度都是 O(1) 。集合中最大的成员数为 2^32 - 1 。

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> ZADD year 1 2008 <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 1 127.0.0.1:6379<span class="token operator">></span> ZADD year 2 2010 <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 1 127.0.0.1:6379<span class="token operator">></span> ZADD year 3 2018 <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 1 127.0.0.1:6379<span class="token operator">></span> ZADD year 3 2018 <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 0 127.0.0.1:6379<span class="token operator">></span> ZADD year 4 2018 <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 0 127.0.0.1:6379<span class="token operator">></span> ZRANGE year 0 10 WITHSCORES 1<span class="token punctuation">)</span> <span class="token string">"2008"</span> 2<span class="token punctuation">)</span> <span class="token string">"1"</span> 3<span class="token punctuation">)</span> <span class="token string">"2010"</span> 4<span class="token punctuation">)</span> <span class="token string">"2"</span> 5<span class="token punctuation">)</span> <span class="token string">"2018"</span> 6<span class="token punctuation">)</span> <span class="token string">"4"</span> 127.0.0.1:6379<span class="token operator">></span> </code></pre>

与有序集合相关的命令

图-8

<h3>
HyperLogLog</h3>

Redis 在 2.8.9 版本添加了 HyperLogLog 结构。

Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的.

在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

什么是基数?

比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为 5 。 基数估计就是在误差可接受的范围内,快速计算基数。

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> PFADD num 1 2 3 4 5 <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 1 127.0.0.1:6379<span class="token operator">></span> PFADD num 2 4 6 8 0 <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 1 127.0.0.1:6379<span class="token operator">></span> PFCOUNT num <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 8 127.0.0.1:6379<span class="token operator">></span> </code></pre>

与 HyperLogLog 相关的命令

图-9

<h3>
发布订阅</h3>

Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。Redis 客户端可以订阅任意数量的频道。

下图展示了三个客户端订阅了同一个频道:

图-10

一旦频道收到某信息,频道会立刻将信息发送到订阅它的客户端:

图-11

以下实例演示了发布订阅是如何工作的:

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> SUBSCRIBE channel1 Reading messages<span class="token punctuation">..</span>. <span class="token punctuation">(</span>press Ctrl-C to quit<span class="token punctuation">)</span> 1<span class="token punctuation">)</span> <span class="token string">"subscribe"</span> 2<span class="token punctuation">)</span> <span class="token string">"channel1"</span> 3<span class="token punctuation">)</span> <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 1 </code></pre>

现在,我们先重新开启个 redis 客户端,然后在同一个频道 channel1 发布两次消息,订阅者就能接收到消息。

<pre><code class="lang-bash hljs">jincheng@LAPTOP-E4NSNKIT:~/SoftWare/redis-5.0.8/src$ ./redis-cli 127.0.0.1:6379<span class="token operator">></span> auth codingbook OK 127.0.0.1:6379<span class="token operator">></span> PUBLISH channel1 hello <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 1 127.0.0.1:6379<span class="token operator">></span> PUBLISH channel1 world <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 1 127.0.0.1:6379<span class="token operator">></span> </code></pre>

此时,之前的打开的客户端显示如下:

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> SUBSCRIBE channel1 Reading messages<span class="token punctuation">..</span>. <span class="token punctuation">(</span>press Ctrl-C to quit<span class="token punctuation">)</span> 1<span class="token punctuation">)</span> <span class="token string">"subscribe"</span> 2<span class="token punctuation">)</span> <span class="token string">"channel1"</span> 3<span class="token punctuation">)</span> <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 1 1<span class="token punctuation">)</span> <span class="token string">"message"</span> 2<span class="token punctuation">)</span> <span class="token string">"channel1"</span> 3<span class="token punctuation">)</span> <span class="token string">"hello"</span> 1<span class="token punctuation">)</span> <span class="token string">"message"</span> 2<span class="token punctuation">)</span> <span class="token string">"channel1"</span> 3<span class="token punctuation">)</span> <span class="token string">"world"</span> </code></pre>

与发布订阅相关的命令

图-12

<h3>
事务</h3>

Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:

<ul><li>批量操作在发送 <code>EXEC</code> 命令前被放入队列缓存。</li><li>收到 <code>EXEC</code> 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。</li><li>在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。</li></ul>

一个事务从开始到执行会经历以下三个阶段:开始事务、命令入队、执行事务。

以下是一个事务的例子, 它先以 <code>MULTI</code> 开始一个事务, 然后将多个命令入队到事务中, 最后由 <code>EXEC</code> 命令触发事务, 一并执行事务中的所有命令:

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> MULTI OK 127.0.0.1:6379<span class="token operator">></span> SET person-name <span class="token string">"jincheng"</span> QUEUED 127.0.0.1:6379<span class="token operator">></span> GET person-name QUEUED 127.0.0.1:6379<span class="token operator">></span> SADD pets <span class="token string">"dog"</span> QUEUED 127.0.0.1:6379<span class="token operator">></span> SMEMBERS pets QUEUED 127.0.0.1:6379<span class="token operator">></span> EXEC 1<span class="token punctuation">)</span> OK 2<span class="token punctuation">)</span> <span class="token string">"jincheng"</span> 3<span class="token punctuation">)</span> <span class="token punctuation">(</span>integer<span class="token punctuation">)</span> 1 4<span class="token punctuation">)</span> 1<span class="token punctuation">)</span> <span class="token string">"dog"</span> 127.0.0.1:6379<span class="token operator">></span> </code></pre>

单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。

与事务相关的命令

图-13

<h3>
脚本</h3>

Redis 脚本使用 Lua 解释器来执行脚本。 Redis 2.6 版本通过内嵌支持 Lua 环境。执行脚本的常用命令为 <code>EVAL</code>。

<code>EVAL</code> 命令的语法如下:

<pre><code class="lang-bash hljs">redis 127.0.0.1:6379<span class="token operator">></span> EVAL script numkeys key <span class="token punctuation">[</span>key <span class="token punctuation">..</span>.<span class="token punctuation">]</span> arg <span class="token punctuation">[</span>arg <span class="token punctuation">..</span>.<span class="token punctuation">]</span> </code></pre>

以下实例演示了 redis 脚本工作过程:

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> EVAL <span class="token string">"return {KEYS[1], KEYS[2], ARGV[1], ARGV[2]}"</span> 2 key1 key2 first second 1<span class="token punctuation">)</span> <span class="token string">"key1"</span> 2<span class="token punctuation">)</span> <span class="token string">"key2"</span> 3<span class="token punctuation">)</span> <span class="token string">"first"</span> 4<span class="token punctuation">)</span> <span class="token string">"second"</span> 127.0.0.1:6379<span class="token operator">></span> </code></pre>

与脚本相关的命令

图-14

<h3>
连接</h3>

Redis 连接命令主要是用于连接 redis 服务。

以下实例演示了客户端如何通过密码验证连接到 redis 服务,并检测服务是否在运行:

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> AUTH codingbook OK 127.0.0.1:6379<span class="token operator">></span> PING PONG 127.0.0.1:6379<span class="token operator">></span> </code></pre>

与连接相关的命令

图-15

<h3>
服务器</h3>

Redis 服务器命令主要是用于管理 redis 服务。

以下实例演示了如何获取 redis 服务器的统计信息:

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> INFO <span class="token comment"># Server</span> redis_version:5.0.8 redis_git_sha1:00000000 redis_git_dirty:0 redis_build_id:3a89591144f2525c redis_mode:standalone os:Linux 4.4.0-18362-Microsoft x86_64 arch_bits:64 multiplexing_api:epoll atomicvar_api:atomic-builtin gcc_version:7.5.0 process_id:155 run_id:7264c9d98ad21bcea11f2ce8ca8b2ba56d7d3a15 tcp_port:6379 uptime_in_seconds:5341 uptime_in_days:0 hz:10 configured_hz:10 lru_clock:9971340 executable:/home/jincheng/SoftWare/redis-5.0.8/src/./redis-server config_file:/home/jincheng/SoftWare/redis-5.0.8/redis.conf <span class="token comment"># Clients</span> connected_clients:1 client_recent_max_input_buffer:2 client_recent_max_output_buffer:0 blocked_clients:0 <span class="token comment"># Memory</span> used_memory:855912 used_memory_human:835.85K used_memory_rss:4136960 used_memory_rss_human:3.95M used_memory_peak:875240 used_memory_peak_human:854.73K used_memory_peak_perc:97.79% used_memory_overhead:841638 used_memory_startup:791488 used_memory_dataset:14274 used_memory_dataset_perc:22.16% allocator_allocated:940232 allocator_active:1212416 allocator_resident:10964992 total_system_memory:8459030528 total_system_memory_human:7.88G used_memory_lua:40960 used_memory_lua_human:40.00K used_memory_scripts:152 used_memory_scripts_human:152B number_of_cached_scripts:1 maxmemory:0 maxmemory_human:0B maxmemory_policy:noeviction allocator_frag_ratio:1.29 allocator_frag_bytes:272184 allocator_rss_ratio:9.04 allocator_rss_bytes:9752576 rss_overhead_ratio:0.38 rss_overhead_bytes:-6828032 mem_fragmentation_ratio:5.08 mem_fragmentation_bytes:3323304 mem_not_counted_for_evict:0 mem_replication_backlog:0 mem_clients_slaves:0 mem_clients_normal:49694 mem_aof_buffer:0 mem_allocator:jemalloc-5.1.0 active_defrag_running:0 lazyfree_pending_objects:0 <span class="token comment"># Persistence</span> loading:0 rdb_changes_since_last_save:0 rdb_bgsave_in_progress:0 rdb_last_save_time:1587029043 rdb_last_bgsave_status:ok rdb_last_bgsave_time_sec:1 rdb_current_bgsave_time_sec:-1 rdb_last_cow_size:0 aof_enabled:0 aof_rewrite_in_progress:0 aof_rewrite_scheduled:0 aof_last_rewrite_time_sec:-1 aof_current_rewrite_time_sec:-1 aof_last_bgrewrite_status:ok aof_last_write_status:ok aof_last_cow_size:0 <span class="token comment"># Stats</span> total_connections_received:9 total_commands_processed:55 instantaneous_ops_per_sec:0 total_net_input_bytes:2153 total_net_output_bytes:12584 instantaneous_input_kbps:0.00 instantaneous_output_kbps:0.00 rejected_connections:0 sync_full:0 sync_partial_ok:0 sync_partial_err:0 expired_keys:0 expired_stale_perc:0.00 expired_time_cap_reached_count:0 evicted_keys:0 keyspace_hits:8 keyspace_misses:0 pubsub_channels:0 pubsub_patterns:0 latest_fork_usec:2982 migrate_cached_sockets:0 slave_expires_tracked_keys:0 active_defrag_hits:0 active_defrag_misses:0 active_defrag_key_hits:0 active_defrag_key_misses:0 <span class="token comment"># Replication</span> role:master connected_slaves:0 master_replid:fbe38bb20ef7a906520b5b343a4f2cc256b7d3c6 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 <span class="token comment"># CPU</span> used_cpu_sys:0.406250 used_cpu_user:0.250000 used_cpu_sys_children:0.031250 used_cpu_user_children:0.000000 <span class="token comment"># Cluster</span> cluster_enabled:0 <span class="token comment"># Keyspace</span> db0:keys<span class="token operator">=</span>6,expires<span class="token operator">=</span>0,avg_ttl<span class="token operator">=</span>0 127.0.0.1:6379<span class="token operator">></span> </code></pre>

与服务器相关的命令

图-16

<h3>
数据备份与恢复</h3>

Redis <code>SAVE</code> 命令用于创建当前数据库的备份。该命令将在 redis 安装目录中创建 dump.rdb 文件。

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> SAVE OK 127.0.0.1:6379<span class="token operator">></span> </code></pre>

现在我们看一下安装目录下是否有该文件:

<pre><code class="lang-bash hljs">jincheng@LAPTOP-E4NSNKIT:~/SoftWare/redis-5.0.8/src$ <span class="token function">cd</span> /home/jincheng/SoftWare/redis-5.0.8/src jincheng@LAPTOP-E4NSNKIT:~/SoftWare/redis-5.0.8/src$ <span class="token function">ls</span> Makefile cluster.o geo.o lzf_c.c rax.h rio.o syncio.o Makefile.dep config.c geohash.c lzf_c.o rax.o scripting.c t_hash.c adlist.c config.h geohash.h lzf_d.c rax_malloc.h scripting.o t_hash.o adlist.h config.o geohash.o lzf_d.o rdb.c sds.c t_list.c adlist.o crc16.c geohash_helper.c memtest.c rdb.h sds.h t_list.o ae.c crc16.o geohash_helper.h memtest.o rdb.o sds.o t_set.c ae.h crc64.c geohash_helper.o mkreleasehdr.sh redis-benchmark sdsalloc.h t_set.o ae.o crc64.h help.h module.c redis-benchmark.c sentinel.c t_stream.c ae_epoll.c crc64.o hyperloglog.c module.o redis-benchmark.o sentinel.o t_stream.o ae_evport.c db.c hyperloglog.o modules redis-check-aof server.c t_string.c ae_kqueue.c db.o intset.c multi.c redis-check-aof.c server.h t_string.o ae_select.c debug.c intset.h multi.o redis-check-aof.o server.o t_zset.c anet.c debug.o intset.o networking.c redis-check-rdb setproctitle.c t_zset.o anet.h debugmacro.h latency.c networking.o redis-check-rdb.c setproctitle.o testhelp.h anet.o defrag.c latency.h notify.c redis-check-rdb.o sha1.c util.c aof.c defrag.o latency.o notify.o redis-cli sha1.h util.h aof.o dict.c lazyfree.c object.c redis-cli.c sha1.o util.o asciilogo.h dict.h lazyfree.o object.o redis-cli.o siphash.c valgrind.sup atomicvar.h dict.o listpack.c pqsort.c redis-sentinel siphash.o version.h bio.c dump.rdb listpack.h pqsort.h redis-server slowlog.c ziplist.c bio.h endianconv.c listpack.o pqsort.o redis-trib.rb slowlog.h ziplist.h bio.o endianconv.h listpack_malloc.h pubsub.c redisassert.h slowlog.o ziplist.o bitops.c endianconv.o localtime.c pubsub.o redismodule.h solarisfixes.h zipmap.c bitops.o evict.c localtime.o quicklist.c release.c sort.c zipmap.h blocked.c evict.o lolwut.c quicklist.h release.h sort.o zipmap.o blocked.o expire.c lolwut.o quicklist.o release.o sparkline.c zmalloc.c childinfo.c expire.o lolwut5.c rand.c replication.c sparkline.h zmalloc.h childinfo.o fmacros.h lolwut5.o rand.h replication.o sparkline.o zmalloc.o cluster.c geo.c lzf.h rand.o rio.c stream.h cluster.h geo.h lzfP.h rax.c rio.h syncio.c jincheng@LAPTOP-E4NSNKIT:~/SoftWare/redis-5.0.8/src$ <span class="token function">find</span> <span class="token keyword">.</span> -name <span class="token string">"dump.rdb"</span> ./dump.rdb jincheng@LAPTOP-E4NSNKIT:~/SoftWare/redis-5.0.8/src$ </code></pre>

可以看到,安装目录下的确有了备份文件。如果需要恢复数据,只需将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可。

BGSAVE

创建 redis 备份文件也可以使用命令 <code>BGSAVE</code>,该命令在后台执行。

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> BGSAVE Background saving started 127.0.0.1:6379<span class="token operator">></span> </code></pre> <h3>
安全</h3>

我们可以通过 redis 的配置文件设置密码参数,这样客户端连接到 redis 服务就需要密码验证,这样可以让你的 redis 服务更安全。

我们可以通过以下命令查看是否设置了密码验证:

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> CONFIG GET requirepass 1<span class="token punctuation">)</span> <span class="token string">"requirepass"</span> 2<span class="token punctuation">)</span> <span class="token string">""</span> 127.0.0.1:6379<span class="token operator">></span> </code></pre>

默认情况下 requirepass 参数是空的,这就意味着你无需通过密码验证就可以连接到 redis 服务。你可以通过以下命令来修改该参数:

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> CONFIG SET requirepass <span class="token string">"codingbook"</span> OK 127.0.0.1:6379<span class="token operator">></span> CONFIG GET requirepass 1<span class="token punctuation">)</span> <span class="token string">"requirepass"</span> 2<span class="token punctuation">)</span> <span class="token string">"codingbook"</span> </code></pre>

设置密码后,客户端连接 redis 服务就需要密码验证,否则无法执行命令。

使用 <code>AUTH</code> 命令进行认证:

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> AUTH codingbook OK 127.0.0.1:6379<span class="token operator">></span> </code></pre> <h3>
性能测试</h3>

Redis 性能测试是通过同时执行多个命令实现的。

redis 性能测试的基本命令如下:

<pre><code class="lang-bash hljs">redis-benchmark <span class="token punctuation">[</span>option<span class="token punctuation">]</span> <span class="token punctuation">[</span>option value<span class="token punctuation">]</span> </code></pre>

注意:该命令是在 redis 的目录下执行的,而不是 redis 客户端的内部指令。

以下实例同时执行 10000 个请求来检测性能:

<pre><code class="lang-bash hljs">jincheng@LAPTOP-E4NSNKIT:~$ <span class="token function">cd</span> /home/jincheng/SoftWare/redis-5.0.8/src/ jincheng@LAPTOP-E4NSNKIT:~/SoftWare/redis-5.0.8/src$ ./redis-benchmark -n 10000 <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span> PING_INLINE <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span> 10000 requests completed <span class="token keyword">in</span> 0.34 seconds 50 parallel clients 3 bytes payload keep alive: 1 90.65% <span class="token operator"><=</span> 1 milliseconds 99.91% <span class="token operator"><=</span> 2 milliseconds 100.00% <span class="token operator"><=</span> 2 milliseconds 29673.59 requests per second <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span> PING_BULK <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span> 10000 requests completed <span class="token keyword">in</span> 0.33 seconds 50 parallel clients 3 bytes payload keep alive: 1 92.36% <span class="token operator"><=</span> 1 milliseconds 99.89% <span class="token operator"><=</span> 2 milliseconds 100.00% <span class="token operator"><=</span> 2 milliseconds 30303.03 requests per second <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span> SET <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span> 10000 requests completed <span class="token keyword">in</span> 0.33 seconds 50 parallel clients 3 bytes payload keep alive: 1 94.34% <span class="token operator"><=</span> 1 milliseconds 100.00% <span class="token operator"><=</span> 1 milliseconds 30581.04 requests per second <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span> GET <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span> 10000 requests completed <span class="token keyword">in</span> 0.33 seconds 50 parallel clients 3 bytes payload keep alive: 1 93.25% <span class="token operator"><=</span> 1 milliseconds 99.91% <span class="token operator"><=</span> 2 milliseconds 100.00% <span class="token operator"><=</span> 2 milliseconds 30211.48 requests per second jincheng@LAPTOP-E4NSNKIT:~/SoftWare/redis-5.0.8/src$ </code></pre>

redis 性能测试工具可选参数如下所示:

图-17

<h3>
客户端连接</h3>

Redis 通过监听一个 TCP 端口或者 Unix socket 的方式来接收来自客户端的连接,当一个连接建立后,Redis 内部会进行以下一些操作:

<ul><li>首先,客户端 socket 会被设置为非阻塞模式,因为 Redis 在网络事件处理上采用的是非阻塞多路复用模型。</li><li>然后为这个 socket 设置 TCP_NODELAY 属性,禁用 Nagle 算法</li><li>然后创建一个可读的文件事件用于监听这个客户端 socket 的数据发送</li></ul>

最大连接数

在 Redis2.4 中,最大连接数是被直接硬编码在代码里面的,而在2.6版本中这个值变成可配置的。maxclients 的默认值是 10000,你也可以在 redis.conf 中对这个值进行修改。

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> CONFIG GET maxclients 1<span class="token punctuation">)</span> <span class="token string">"maxclients"</span> 2<span class="token punctuation">)</span> <span class="token string">"10000"</span> 127.0.0.1:6379<span class="token operator">></span> </code></pre>

也可以在启动服务器的时候指定最大连接数:

<pre><code class="lang-bash hljs">redis-server --maxclients 100000 </code></pre>

客户端命令

图片-18

<h3>
管道技术</h3>

Redis是一种基于客户端-服务端模型以及请求/响应协议的 TCP 服务。这意味着通常情况下一个请求会遵循以下步骤:

<ul><li>客户端向服务端发送一个查询请求,并监听 Socket 返回,通常是以阻塞模式,等待服务端响应。</li><li>服务端处理命令,并将结果返回给客户端。</li></ul>

Redis 管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。

<pre><code class="lang-bash hljs">127.0.0.1:6379<span class="token operator">></span> <span class="token punctuation">(</span>echo -en <span class="token string">"PING\r\n SET tool redis\r\nGET tool\r\nINCR visitor\r\nINCR visitor\r\nINCR visitor\r\n"</span><span class="token punctuation">;</span> <span class="token function">sleep</span> 10<span class="token punctuation">)</span> <span class="token operator">|</span> nc localhost 6379 PONG OK redis :1 :2 :3 127.0.0.1:6379<span class="token operator">></span> </code></pre>

以上实例中我们通过使用 PING 命令查看 redis 服务是否可用, 之后我们设置了 tool 的值为 redis,然后我们获取 tool 的值并使得 visitor 自增 3 次。在返回的结果中我们可以看到这些命令一次性向 redis 服务提交,并最终一次性读取所有服务端的响应。

<h3>
分区</h3>

分区是分割数据到多个 Redis 实例的处理过程,因此每个实例只保存 key 的一个子集。

分区的优势

<ul><li>通过利用多台计算机内存的和值,允许我们构造更大的数据库。</li><li>通过多核和多台计算机,允许我们扩展计算能力;通过多台计算机和网络适配器,允许我们扩展网络带宽。</li></ul>

分区的不足

<ul><li>redis 的一些特性在分区方面表现的不是很好:</li><li>涉及多个 key 的操作通常是不被支持的。举例来说,当两个 set 映射到不同的 redis 实例上时,你就不能对这两个 set 执行交集操作。</li><li>涉及多个 key 的 redis 事务不能使用。</li><li>当使用分区时,数据处理较为复杂,比如你需要处理多个 rdb/aof 文件,并且从多个实例和主机备份持久化文件。</li><li>增加或删除容量也比较复杂。redis 集群大多数支持在运行时增加、删除节点的透明数据平衡的能力,但是类似于客户端分区、代理等其他系统则不支持这项特性。然而,一种叫做 presharding 的技术对此是有帮助的。</li></ul>

分区类型

Redis 有两种类型分区。 假设有 4 个 Redis 实例 R0,R1,R2,R3,和类似 user:1,user:2 这样的表示用户的多个 key ,对既定的 key 有多种不同方式来选择这个 key 存放在哪个实例中。也就是说,有不同的系统来映射某个 key 到某个 Redis 服务。

范围分区

最简单的分区方式是按范围分区,就是映射一定范围的对象到特定的 Redis 实例。

比如,ID 从 0 到 10000 的用户会保存到实例 R0,ID 从 10001 到 20000 的用户会保存到R1,以此类推。

这种方式是可行的,并且在实际中使用,不足就是要有一个区间范围到实例的映射表。这个表要被管理,同时还需要各 种对象的映射表,通常对 Redis 来说并非是好的方法。

哈希分区

另外一种分区方法是 hash 分区。这对任何 key 都适用,也无需是 object_name: 这种形式,像下面描述的一样简单:

<ul><li>用一个 hash 函数将 key 转换为一个数字,比如使用 crc32 hash 函数。对 key foobar 执行 crc32(foobar) 会输出类似 93024922 的整数。</li><li>对这个整数取模,将其转化为 0-3 之间的数字,就可以将这个整数映射到 4 个 Redis 实例中的一个了。93024922 % 4 = 2,就是说 key foobar 应该被存到 R2 实例中。注意:取模操作是取除的余数,通常在多种编程语言中用 % 操作符实现。</li></ul> 到此这篇关于“Redis基础教程”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
PHP Redis相关操作大全
REDIS基础, GO语言
PHP操作Redis数据库常用方法(总结)
PHP操作Redis数据库常用方法
PHP操作Redis的基本方法
redis的基础数据结构之 sds
PHP Redis发布订阅
30 个 php 操作 redis 常用方法代码示例
超全的!Redis的安装和基础操作
Golang基础学习-redis使用

[关闭]
~ ~