虚拟化高性能NoSQL存储案例精粹 Redis+Docker

978-7-115-55448-2
作者: 高洪岩
译者:
编辑: 陈聪聪
分类: NoSQL

图书目录:

详情

《虚拟化高性能NoSQL存储案例精粹——Redis+Docker》主要介绍虚拟化平台Docker结合NoSQL、Redis开发的相关知识点。本书使用大量篇幅着重介绍Redis中的五大数据类型的使用方法,包括String、Hash、List、Set和Sorted Set,还介绍了使用Redis实现高可用的哨兵、复制、集群、高性能数据导入的流水线,以及保障数据操作原子性的事务。另外,本书对Redis中的数据持久化方案AOF和RDB也进行了详细介绍,并对HyperLogLog、GEO和Pub/Sub的相关知识进行了总结,结合实战经验丰富了与内存淘汰策略相关的内容。虚拟化技术使用Docker实现,包括Docker环境的搭建、常见命令的使用、对镜像和容器的操作,以及常见技术的容器的创建。 《虚拟化高性能NoSQL存储案例精粹——Redis+Docker》适合所有使用Redis进行编程的开发人员、服务器和数据存储系统开发人员、分布式系统架构师等互联网技术程序员阅读。

图书摘要

版权信息

书名:虚拟化高性能NoSQL存储案例精粹——Redis+Docker

ISBN:978-7-115-55448-2

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

著    高洪岩

责任编辑 陈聪聪

人民邮电出版社出版发行  北京市丰台区成寿寺路11号

邮编 100164  电子邮件 315@ptpress.com.cn

网址 http://www.ptpress.com.cn

读者服务热线:(010)81055410

反盗版热线:(010)81055315


本书主要介绍虚拟化平台Docker结合NoSQL、Redis开发的相关知识点。本书使用大量篇幅着重介绍Redis中的五大数据类型的使用方法,包括String、Hash、List、Set和Sorted Set,还介绍了使用Redis实现高可用的哨兵、复制、集群、高性能数据导入的流水线,以及保障数据操作原子性的事务。另外,本书对Redis中的数据持久化方案AOF和RDB也进行了详细介绍,并对HyperLogLog、GEO和Pub/Sub的相关知识进行了总结,结合实战经验丰富了与内存淘汰策略相关的内容。虚拟化技术使用Docker实现,包括Docker环境的搭建、常见命令的使用、对镜像和容器的操作,以及常见技术的容器的创建。

本书适合所有使用Redis进行编程的开发人员、服务器和数据存储系统开发人员、分布式系统架构师等互联网技术程序员阅读。


本书由异步社区出品,社区(https://www.epubit.com/)为您提供相关资源和后续服务。

本书提供如下资源:

要获得以上配套资源,请在异步社区本书页面中单击,跳转到下载界面,按提示进行操作即可。注意:为保证购书读者的权益,该操作会给出相关提示,要求输入提取码进行验证。

作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎您将发现的问题反馈给我们,帮助我们提升图书的质量。

当您发现错误时,请登录异步社区,按书名搜索,进入本书页面,单击“提交勘误”,输入勘误信息,单击“提交”按钮即可。本书的作者和编辑会对您提交的勘误进行审核,确认并接受后,您将获赠异步社区的100积分。积分可用于在异步社区兑换优惠券、样书或奖品。

我们的联系邮箱是contact@epubit.com.cn。

如果您对本书有任何疑问或建议,请您发邮件给我们,并请在邮件标题中注明本书书名,以便我们更高效地做出反馈。

如果您有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们;有意出版图书的作者也可以到异步社区在线提交投稿(直接访问www.epubit.com/selfpublish/submission即可)。

如果您所在的学校、培训机构或企业,想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。

如果您在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请您将怀疑有侵权行为的链接发邮件给我们。您的这一举动是对作者权益的保护,也是我们持续为您提供有价值的内容的动力之源。

“异步社区”是人民邮电出版社旗下IT专业图书社区,致力于出版精品IT技术图书和相关学习产品,为作译者提供优质出版服务。异步社区创办于2015年8月,提供大量精品IT技术图书和电子书,以及高品质技术文章和视频课程。更多详情请访问异步社区官网https://www.epubit.com。

“异步图书”是由异步社区编辑团队策划出版的精品IT专业图书的品牌,依托于人民邮电出版社近30年的计算机图书出版积累和专业编辑团队,相关图书在封面上印有异步图书的LOGO。异步图书的出版领域包括软件开发、大数据、AI、测试、前端、网络技术等。

异步社区

微信服务号


NoSQL全称是Not Only SQL(不仅仅是SQL),它属于非关系型数据库(Non-Relational DB)。

NoSQL的存储结构主要有两个特点。

NoSQL是一类数据库的统称,并不是某一个具体的数据库产品名称,就像关系型数据库管理系统(Relational Database Managemet System,RDBMS)一样。

RDBMS包括Oracle、MySQL以及MS SQL Server,NoSQL包括Redis、MangoDB等。

RDBMS的缺点如下。

列数有限:常见的RDBMS允许一张表最大支持的列数是有限制的,其中Oracle最多支持1000列。

行数有限:在RDBMS中,如果一张表中的行数达到百万级时,那么读写的速度会呈断崖式下降。

在使用RDBMS时,面对海量数据必须使用主从复制、分库分表。这样的系统架构是难以维护的,其维护成本比较高,因为它增加了程序员在开发和运维时的工作量,而且在海量数据下使用select查询语句效率极低,查询时间会呈指数级增长。

但NoSQL可以解决上面4个问题。

NoSQL有自己的优势和使用场景,在软件公司中应用比较多。

NoSQL的优势可以总结为如下4点。

NoSQL具有非常良好的读写性能,尤其在面对海量数据时表现同样优秀。这得益于它的非关系性和结构简单。Redis的作者在设计Redis时,最优先考虑的就是性能。

使用NoSQL时不需要创建列,它的数据格式比较灵活。

NoSQL具有主从复制、支持集群等特点,大大增强了软件项目的高可用性。如果某一台计算机宕机,那么其他的计算机会接手任务,不至于出现系统无法访问的情况。

这是大多数NoSQL共有的特点,因为多数NoSQL是免费开源的,所以没有高昂的授权成本。

RDBMS和NoSQL都有各自的优势和使用场景,两者需要结合使用。让关系型数据库关注在关系上,让NoSQL关注在存储上。

“一针见血”总结NoSQL优势:因为RDBMS太慢,所以用NoSQL!

一个事物有优势就有劣势,NoSQL的劣势可以总结为如下5点。

Redis的作者是萨尔瓦托雷·圣菲利波(Salvatore Sanfilippo),他来自意大利的西西里岛,被称为Redis之父。

Redis全称是Remote Dictionary Server,它是现阶段极为流行的NoSQL之一,它以键-值(key-value)对的形式在内存中保存数据。Redis的读写性能非常高,如果硬件环境非常优秀,可以实现每秒插入10万条记录,因此Redis常用于存储、缓存等场景。

Redis可以将内存中的数据持久化到硬盘上,防止因为出现断电、死机等造成数据丢失,还支持key超时、发布订阅、流水线(批处理)以及Lua脚本等。

Redis主要有如下特点。

Redis在软件系统中的位置如图1-1所示。

图1-1 Redis在软件系统中的位置

Redis常作为数据的缓存。当业务层需要数据时首先从Redis中获取,如果Redis中没有数据,则通过数据访问层去访问真正的RDBMS并取得数据,将取得的数据由业务层放入Redis中,以便业务层下一次访问时直接从Redis中获取想要的数据,而不必访问运行效率较低的RDBMS,这样提高了系统运行效率。Redis还可以实现队列、排行榜和计数器等。

Redis运行环境不支持Windows,所谓Windows版本的Redis其实是微软公司的开发小组模仿Redis的功能写的,并不是原版的Redis。它更新进度较慢,功能较官方的Redis少很多。

因为Redis官方并没有Windows版本,所以要在Linux虚拟机环境下学习Redis。

本书使用VirtualBox结合Ubuntu搭建Linux环境。

建议在断网的情况下安装Ubuntu,以省略在线更新的步骤,加快安装速度。

VirtualBox是一款开源虚拟机软件,由德国Innotek公司开发,Sun公司出品,使用Qt编写,在Sun公司被Oracle收购后正式更名为Oracle VM VirtualBox。VirtualBox为经典的最强的免费虚拟机软件之一,它不仅具有丰富的功能,而且性能也很高。

进入VirtualBox官网,单击“Downloads”下载VirtualBox安装文件,如图1-2所示。

图1-2 下载VirtualBox安装文件

下载针对Windows的VirtualBox binaries版本,如图1-3所示。

图1-3 下载针对Windows的VirtualBox binaries版本

下载成功后安装VirtualBox。

本节步骤较多,主要介绍在VirtualBox中安装Ubuntu(即安装虚拟机),并在安装过程中设置Ubantu有关的参数。

从阿里巴巴开源镜像站下载Ubuntu或CentOS镜像文件,进入VirtualBox后单击“新建”按钮创建新的虚拟机,如图1-4所示。

图1-4 单击“新建”按钮

设置虚拟机名称和保存路径,如图1-5所示。

为虚拟机分配使用的内存,如图1-6所示。

图1-5 设置虚拟机名称和保存路径

图1-6 为虚拟机分配使用的内存

创建虚拟硬盘,如图1-7所示。

选择虚拟硬盘文件类型,如图1-8所示。

图1-7 创建虚拟硬盘

图1-8 选择虚拟硬盘文件类型

动态分配虚拟硬盘空间,如图1-9所示。

设置VDI文件保存的路径并对虚拟硬盘分配极限使用空间,这里设置为100GB,如图1-10所示。

图1-9 动态分配虚拟硬盘空间

图1-10 对虚拟硬盘分配极限使用空间

单击“创建”按钮,显示界面,单击“启动”按钮开始安装Ubuntu,如图1-11所示。

图1-11 单击“启动”按钮

弹出对话框选择ubuntu.iso镜像文件。

单击“启动”按钮,如图1-12所示。

图1-12 单击“启动”按钮

开始进入安装Ubuntu的流程。

选择“中文(简体)”,并单击“安装Ubuntu”按钮。选择“汉语”。

配置安装选项,选择“正常安装”,为了在安装时不需要大量耗时,取消勾选“安装Ubuntu时下载更新”,如图1-13所示。

选择安装类型,如图1-14所示。

图1-13 配置安装选项

图1-14 选择安装类型

确认磁盘分区,如图1-15所示。

选择Beijing时区。

设置用户名和密码,如图1-16所示。

图1-15 确认磁盘分区

图1-16 设置用户名和密码

单击“继续”按钮后在线下载必需的文件并安装Ubuntu自带的软件,此过程用时较长,如图1-17所示。

下载语言包用时也较长,如图1-18所示。

安装成功后重启计算机,如图1-19所示。

图1-17 在线下载必需的文件并安装Ubuntu自带的软件

图1-18 下载语言包

图1-19 重启计算机

使用VirtualBox安装的Ubuntu由于在安装过程中没有对root用户设置密码,因此在启动虚拟机后使用如下命令重置root密码,如图1-20所示。

图1-20 重置root密码

sudo passwd root

在Linux中安装软件默认从官网进行下载,速度较慢,可以使用国内的阿里云下载源。

1.查看/etc/apt/sources.list文件

配置阿里云下载源的文件是/etc/apt/sources.list,使用如下命令查看sources.list文件。

sudo gedit /etc/apt/sources.list

从sources.list 文件中的URL来看,它们都是国外的网站,因此下载速度比较慢。

如果想使用国内的下载源,如阿里云下载源,那么要先知道所运行Ubuntu的版本。因为sources.list文件中的内容与Ubuntu版本相对应,Ubuntu版本不同,sources.list文件中的内容也不同。

2.获得Ubuntu版本

使用如下命令查看Ubuntu版本。

uname -a

显示内容如图1-21所示。

图1-21 显示内容

当前Ubuntu的版本是18.04.1。

3.在阿里巴巴开源镜像站中获得sources.list文件中的内容

在虚拟机中输入网址,找到ubuntu链接并单击,如图1-22所示。

图1-22 找到ubuntu链接并单击

当前环境使用的Ubuntu版本为18.04,而18.04的别名就是“bionic”,因此要使用相应配置,单击复制超链接即可。

使用如下命令。

sudo gedit /etc/apt/sources.list

 

注意:gedit命令和路径/etc/apt/sources.list之间有空格。

 

将sources.list文件的全部内容替换:

Ubuntu已经转为使用阿里云的下载源了,更新系统环境设置,把阿里云上面的软件信息下载到本地缓存中,运行如下命令。

sudo apt-get update

apt-get update命令会从阿里云读取软件列表,然后将其保存在本地进行缓存。

再运行如下命令。

sudo apt-get upgrade

此命令会把本地已安装的软件与刚下载到本地缓存的软件列表中的每一个软件进行版本对比,如果发现已安装的软件版本太低就进行软件更新。

Update命令用于更新软件列表,upgrade用于命令更新软件。

在使用Ubuntu的过程中可能需要更改一些配置文件,除了使用gedit命令外还可以使用Vim文本编辑器。在当前系统环境中,默认没有安装Vim文本编辑器,如图1-23所示。

图1-23 没有安装Vim文本编辑器

使用如下命令安装Vim文本编辑器。

apt install vim

在终端输入如下命令。

vim

进入Vim文本编辑器,其界面如图1-24所示。

图1-24 Vim文本编辑器界面

要想退出Vim文本编辑器,可以按“Esc”键后再输入如下命令。

:q

默认情况下,VirtualBox文本编辑器不支持和宿主主机的复制和粘贴操作,需要进行配置。

进入系统后单击“控制”菜单中的“设置”子菜单,如图1-25所示。

设置“共享粘贴板”和“拖放”为“双向”,设置完成后单击“OK”按钮保存设置,如图1-26所示。

图1-25 单击“设置”子菜单

图1-26 设置为“双向”

单击“设备”菜单中的“安装增强功能”子菜单,如图1-27所示。

弹出对话框单击“运行”按钮,如图1-28所示。

图1-27 单击“安装增强功能”子菜单

图1-28 单击“运行”按钮

如果没有弹出对话框,则进入光驱软件,单击右上角的“运行软件”按钮,如图1-29所示。

图1-29 单击“运行软件”按钮

开始安装增强功能,但出现异常,提示没有“gcc make perl packages”,如图1-30所示。

图1-30 提示没有“gcc make perl packages”

使用如下命令安装“gcc make perl packages”。

sudo apt-get install build-essential gcc make perl dkms

安装成功后再运行如下命令进行系统重启。

reboot

如果“gcc make perl packages”安装成功,系统重启后说明“gcc make perl packages”在系统中存在,则继续双击光驱软件,单击右上角的“运行软件”按钮,如图1-31所示。

图1-31 继续单击“运行软件”按钮

成功安装增强功能,这次并没有出现异常,如图1-32所示。

图1-32 成功安装增强功能

操作至此,双向复制粘贴和增强功能设置完成。

ifconfig命令可以查看网卡信息,效果如下。

ghy@ghy-VirtualBox:~$ ifconfig

Command 'ifconfig' not found, but can be installed with:

sudo apt install net-tools

但默认情况下Ubuntu并没有安装相关命令,执行如下命令开始安装ifconfig命令。

ghy@ghy-VirtualBox:~$ sudo apt install net-tools

在虚拟机中使用桥连接与Redis进行通信的方式如图1-33所示。

图1-33 使用桥连接

本节开始介绍搭建Redis环境的方法。

进入Redis官网,如图1-34所示。

图1-34 进入Redis官网

在官网下载Redis,文件名为redis-version.tar.gz。

本节介绍如何在Ubuntu中搭建Redis环境。

1.执行make命令进行编译

将redis-version.tar.gz文件复制到Ubuntu并解压,解压到主文件夹中的T/redis文件夹里,解压的位置如图1-35所示。

图1-35 解压的位置

在终端中进入解压的文件夹,然后执行make命令开始编译Redis并生成其他依赖的文件,如图1-36所示。

图1-36 执行make命令开始编译Redis

但却提示没有找到make命令,可以使用如下命令进行安装。

sudo apt install make

但在中途可能会出现锁资源的情况,解决的步骤如下。

ghy@ubuntu:~/T/redis$ sudo apt install make
E: 无法获得锁 /var/lib/dpkg/lock-frontend - open (11: 资源暂时不可用)
E: 无法获取 dpkg 前端锁 (/var/lib/dpkg/lock-frontend),是否有其他进程正占用它?
ghy@ubuntu:~/T/redis$ sudo rm /var/lib/dpkg/lock-frontend
ghy@ubuntu:~/T/redis$ sudo apt install make
正在读取软件包列表... 完成
正在分析软件包的依赖关系树   
正在读取状态信息... 完成

建议安装如下内容。

  make-doc
E: 无法获得锁 /var/cache/apt/archives/lock - open (11: 资源暂时不可用)
E: 无法对目录 /var/cache/apt/archives/ 加锁
ghy@ubuntu:~/T/redis$ sudo rm /var/cache/apt/archives/lock
ghy@ubuntu:~/T/redis$ sudo apt install make
正在读取软件包列表... 完成
正在分析软件包的依赖关系树   
正在读取状态信息... 完成

建议安装如下内容。

  make-doc

下列新软件包将被安装。

  make

升级了0个软件包,新安装了1个软件包,卸载了0个软件包,有119个软件包未被升级。

需要下载154 KB的文档。解压后会消耗381 KB的额外空间。

获取:1 http://us.archive.ubuntu.com/ubuntu bionic/main amd64 make amd64 4.1-9.1ubuntu1 [154 KB]
已下载 154 kB,耗时 4s (40.4 KB/s)
正在选中未选择的软件包 make。
(正在读取数据库 ... 系统当前共安装有 128211 个文件和目录。)
正准备解包 .../make_4.1-9.1ubuntu1_amd64.deb  ...
正在解包 make (4.1-9.1ubuntu1) ...
正在设置 make (4.1-9.1ubuntu1) ...
正在处理用于 man-db (2.8.3-2ubuntu0.1) 的触发器 ...
ghy@ubuntu:~/T/redis$

再次执行make命令,可能出现没有gcc命令的提示,如图1-37所示。

图1-37 没有gcc命令

使用如下命令安装gcc命令。

sudo apt install gcc

gcc命令安装成功后再次执行make命令进行编译,又可能出现找不到jemalloc.h的异常,如图1-38所示。

图1-38 找不到jemalloc.h的异常

使用如下命令继续编译。

make MALLOC=libc

编译结束后如图1-39所示。

图1-39 编译结束

并没有出现异常,说明编译正确。

2.执行make test命令进行测试

在终端中输入make test命令来进行测试,该命令的作用是测试Redis是否可以正确执行。

在终端中输入如下命令。

make test

出现异常,如图1-40所示。

异常如下。

You need tcl 8.5 or newer in order to run the Redis test

提示当前安装的tcl版本较旧,至少需要8.5以上的版本,tcl需要升级,输入如下命令。

sudo apt install tcl

再次执行如下命令。

make test

测试通过并没有发现错误,终端显示图1-41所示的内容。

以上步骤结束后,证明Redis在Ubuntu中编译成功,下一步就是将Redis安装到Ubuntu中。

图1-40 出现异常

图1-41 测试通过并没有发现错误

3.执行make install命令安装Redis

make install命令的作用是将redis/src中的命令复制到/usr/local/bin路径中,这样就可以在任意的路径下执行Redis的命令了。

在终端执行如下命令。

make install

输出信息如图1-42所示。

make install命令执行完毕后, /usr/local/bin路径中存在与Redis相关的可执行文件,如图1-43所示。

其中可执行文件redis-server是Redis的服务器,而可执行文件redis-cli(Redis Command Line Interface)是Redis的客户端。

图1-42 输出信息

图1-43  /usr/local/bin路径中存在与Redis相关的可执行文件

4.查看Redis的版本

使用redis-cli命令查看Redis的版本,命令如下。

ghy@ubuntu:~$ redis-cli -v
redis-cli 5.0.5
ghy@ubuntu:~$

本节将在CentOS中搭建Redis环境。

1.执行make命令进行编译

将redis-version.tar.gz文件复制到CentOS并解压,解压到主文件夹中的T/redis文件夹里,解压的位置如图1-44所示。

图1-44 解压的位置

在终端中进入解压的文件夹,然后执行make命令开始编译Redis并生成其他依赖的文件,如图1-45所示。

编译结束后如图1-46所示。

图1-45 执行make命令开始编译Redis

图1-46 编译结束

并没有出现异常,说明编译正确。

2.执行make test命令进行测试

在终端中输入make test命令来进行测试,该命令的作用是测试Redis是否可以正确执行。

在终端中输入如下命令。

make test

出现异常,如图1-47所示。

图1-47 出现异常

异常如下。

You need tcl 8.5 or newer in order to run the Redis test

提示当前安装的tcl版本较旧,至少需要8.5以上的版本,tcl需要升级,输入如下命令。

 [ghy@localhost redis]$ su
密码:
[root@localhost redis]# yum install tcl

在执行su命令后输入root密码,确认切换到[root@localhost redis]用户才是正确的。

开始安装新版tcl,安装成功后如图1-48所示。

再次执行如下命令。

make test

测试通过并没有发现错误,终端显示图1-49所示内容。

图1-48 安装成功

图1-49 测试通过并没有发现错误

以上步骤结束后证明Redis在CentOS中编译成功,下一步就是将Redis安装到CentOS中。

3.执行make install命令安装Redis

make install命令的作用是将redis/src中的命令复制到/usr/local/bin路径中,这样就可以在任意的路径下执行Redis命令了。

在终端执行如下命令。

make install

输出信息如图1-50所示。

make install命令执行完毕后,/usr/local/bin路径中存在与Redis相关的可执行文件,如图1-51所示。

图1-50 输出信息

图1-51 /usr/local/bin路径中存在与Redis相关的可执行文件

其中可执行文件redis-server是Redis的服务器,可执行文件redis-cli是Redis的客户端。

4.查看Redis的版本

使用redis-cli命令查看Redis的版本,命令如下。

 [root@localhost redis]# redis-cli -v
redis-cli 5.0.5
[root@localhost redis]#

启动Redis服务可以通过如下几种方式实现。

启动Redis服务可以通过在终端输入如下命令实现。

redis-server

成功启动Redis服务,如图1-52所示。

终端显示Redis的默认端口号为6379。

Redis服务启动后可以通过ps命令查看Redis进程信息,打开新的终端并执行ps命令,如图1-53所示。

图1-52 成功启动Redis服务

图1-53 查看Redis进程信息

强制停止Redis服务可以通过在启动Redis服务的终端中按“Ctrl+C”快捷键实现。

直接执行redis-server命令来启动Redis服务的方式是不推荐使用的,因为这样使用的都是Redis默认的配置,有端口号不可以指定、Redis服务器没有设置密码等缺陷,解决的办法是结合redis.conf配置文件来启动Redis服务,后文会进行介绍。

使用redis-server &命令来启动Redis服务并不是以后台的模式运行的,在当前的终端中并不允许输入其他的命令,可以使用如下命令实现后台运行模式。

redis-server &

Redis服务启动后可以在当前终端中输入其他命令。

当以后台的模式运行Redis服务时,按“Ctrl+C”快捷键就无效了,可以使用kill命令强制结束进程,如图1-54所示。

图1-54 强制结束进程

使用如下命令会把Redis服务在终端上输出的信息保存在nohup.out文件里。

nohup redis-server &

强制停止Redis服务可以使用“Ctrl+C”快捷键或kill命令,但建议不要这样做,较好的方式是在新打开的终端中输入如下命令。

redis-cli shutdown

命令执行后Redis服务的终端显示图1-55所示的信息。

图1-55 Redis服务的终端显示信息

使用redis-cli shutdown命令来停止Redis服务可以将当前正在处理中的任务继续执行,直到执行完毕再停止Redis服务,在这个过程中不再接收新的Redis客户端请求,所以使用此种方式来停止Redis服务是推荐使用的。

 

注意:坚决不要使用或kill命令“Ctrl+C”快捷键以“暴力”方式强制结束Redis进程,这样会造成数据的丢失。

 

使用redis-server命令启动Redis服务,在新的终端中执行redis-benchmark命令,测试Redis服务性能,命令如下。

redis-benchmark -p 6379

-p 6379代表对连接使用6379端口的Redis服务进行性能测试。

命令执行后统计出命令执行效率的相关信息,如SET命令和GET命令的执行效率统计结果如下。

====== SET ======
  100000 requests completed in 1.79 seconds
  50 parallel clients
  3 bytes payload
  keep alive: 1

98.36% <= 1 milliseconds
99.20% <= 2 milliseconds
99.63% <= 3 milliseconds
99.80% <= 6 milliseconds
99.88% <= 7 milliseconds
99.90% <= 8 milliseconds
99.95% <= 11 milliseconds
100.00% <= 11 milliseconds
55865.92 requests per second

SET命令每秒请求55865.92次。

====== GET ======
  100000 requests completed in 1.74 seconds
  50 parallel clients
  3 bytes payload
  keep alive: 1

99.03% <= 1 milliseconds
99.40% <= 2 milliseconds
99.85% <= 3 milliseconds
99.90% <= 4 milliseconds
99.93% <= 5 milliseconds
99.95% <= 8 milliseconds
99.97% <= 9 milliseconds
100.00% <= 9 milliseconds
57636.89 requests per second

GET命令每秒请求57636.89次。

但不要以该执行效率作为当前计算机运行的Redis服务性能的指标,它只是一个参考值,真实的性能还要结合实际的业务场景进行测试。

可以使用两种方式更改Redis服务的端口号。

在终端输入如下命令。

redis-server --port 8888

之后Redis服务的端口号为8888,如图1-56所示。

图1-56 端口号为8888

使用如下命令停止指定端口的Redis服务。

redis-cli -p 8888 shutdown

Redis服务已停止。

编辑redis.conf配置文件中的port属性,更改端口号为7777,配置文件内容如图1-57所示。

图1-57 配置文件内容

使用如下命令。

[gaohongyan@localhost redis]$ redis-server redis.conf

启动Redis服务,新端口号如图1-58所示。

图1-58 新端口号

使用如下命令可以停止Redis服务。

redis-cli -p 7777 shutdown

编辑redis.conf配置文件中的requirepass属性,设置密码为accp,如图1-59所示。

图1-59 设置密码

使用如下命令启动Redis服务。

[gaohongyan@localhost redis]$ redis-server redis.conf

在新打开的终端中使用redis-cli命令连接Redis服务,并使用keys *命令查询数据,如图1-60所示。

图1-60 查询数据

出现“ (error) NOAUTH Authentication required.”异常,原因就是没有使用密码进行登录。按“Ctrl+C”快捷键停止Redis服务,在终端中再执行命令,如图1-61所示,在登录时使用-a参数添加密码accp。

图1-61 使用密码进行登录

成功使用密码进行登录。

再执行keys *命令不再出现异常,效果如下。

127.0.0.1:7777> keys *
1) "mylist"
2) "myset:__rand_int__"
3) "counter:__rand_int__"
4) "key:__rand_int__"
127.0.0.1:7777>

Redis中自带了4条记录。

如果在主机和虚拟机环境中,并且在互联网环境中想要让Redis服务器被其他计算机访问还需要做一些更改。

默认情况下,如果bind配置呈被注释的状态,则Redis服务器将监听所有网卡的连接,等同于配置bind 0.0.0.0。

可以使用bind配置监听指定的一块或多块网卡的连接。

bind ip1
bind ip1 ip2

为什么要使用bind配置只监听指定的网卡呢?如果Redis服务器监听多块网卡,如监听内网和外网两块网卡,不使用bind配置,则在互联网环境下通过外网网卡可以直接访问Redis服务器,完全可以在互联网环境下进行密码嗅探,对Redis服务器的安全非常不利。如果Redis服务器运行的环境是在内网中,不想被互联网环境下的其他客户端所访问,这时可以使用bind 配置。限制Redis服务器只能通过内网网卡进行访问,增强了安全性。

如果使用配置bind 127.0.0.1,则Redis服务器只能被当前服务器所访问,其他服务器不能访问。

在redis-cli命令中使用-h参数连接远程Redis服务器,命令如下。

[gaohongyan@localhost ~]$ redis-cli -h localhost -p 7777 -a accp
Warning: Using a password with '-a' option on the command line interface may not be safe.
localhost:7777>

localhost可以换成远程Redis服务器的IP地址。

如果在redis-cli命令中没有使用-h和-p参数,则默认连接127.0.0.1:6379的Redis服务器。

如果虚拟机没有IP地址,可以依次输入如下命令来解决。

另外,如果无线网卡和有线网卡同时连接到不同的网段也会出现没有IP地址的情况。

使用如下命令存取值。

localhost:7777> set username gaohongyan
OK
localhost:7777> get username
"gaohongyan"

set命令的作用就是向指定的key存储对应的value。

get命令的作用就是根据指定的key获取对应的value。

如果set命令存储的是中文,则get命令获取的数据其实是经过编码后的值,效果如下。

[ghy@localhost ~]$ redis-cli -p 6379
127.0.0.1:6379> set username 我是中国人
OK
127.0.0.1:6379> get username
"\xe6\x88\x91\xe6\x98\xaf\xe4\xb8\xad\xe5\x9b\xbd\xe4\xba\xba"
127.0.0.1:6379>

想显示正确中文的解决办法是对redis-cli命令使用--raw参数,效果如下。

[ghy@localhost ~]$ redis-cli -p 6379 --raw
127.0.0.1:6379> get username
我是中国人
127.0.0.1:6379>

key的名称建议设置为如下的格式。

业务名称:对象名:id:属性

如MySQL数据库中有一个userinfo表,表中有id、username和password这3个列,可以使用如下格式来代表MySQL数据库中的一行记录。

mysql:userinfo:id:username
mysql:userinfo:id:password

对应的set和get命令如下。

127.0.0.1:7777> set mysql.userinfo.123.username ghy1
OK
127.0.0.1:7777> set mysql.userinfo.123.password 123
OK
127.0.0.1:7777> set mysql.userinfo.456.username ghy2
OK
127.0.0.1:7777> set mysql.userinfo.456.password 456
OK
127.0.0.1:7777> get mysql.userinfo.123.username
"ghy1"
127.0.0.1:7777> get mysql.userinfo.123.password
"123"
127.0.0.1:7777> get mysql.userinfo.456.username
"ghy2"
127.0.0.1:7777> get mysql.userinfo.456.password
"456"
127.0.0.1:7777>

按照1.14节中的步骤连接远程Redis服务器后,进入Redis Desktop Manager图形界面工具的主界面,如图1-62所示。

图1-62 主界面

单击主界面左上角“连接到Redis服务器” 按钮,弹出界面如图1-63所示。

图1-63 弹出界面

单击左下角的“测试连接”按钮,出现“连接Redis服务器成功”的提示框,单击“OK”按钮关闭提示框。

双击myRedis连接后,查看数据库的数据,如图1-64所示。

图1-64 查看数据库的数据

在Java中操作Redis的Java Client API产品很多,所以其使用率较高,这得益于它的API的简洁,易于上手。

操作Redis至少需要4个JAR包,如图1-65所示。

图1-65 4个JAR包

操作Redis可以使用.java类,但.java类并不是线程安全的,如果在多线程环境下,多个线程使用同一个.java类的对象则会出现一些奇怪的问题,这时可以使用Pool类进行解决。Pool类可以在多线程环境下正常安全地工作,每个线程都拥有自己独有的对象,使用完毕后再放回池中以便进行复用。可以将Pool类声明成static静态的,示例程序如下。

package test;

import redis.clients..;
import redis.clients..Pool;
import redis.clients..PoolConfig;

public class Test1 {
    private static Pool pool = new Pool(new PoolConfig(), "192.168.1.105", 7777, 5000, "accp");

    public static void main(String[] args) {
          = null;
        try {
             = pool.getResource();
            .set("username", "我是中国人");
            String username = .get("username");
            System.out.println(username);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if ( != null) {
                 .close();
            }
        }
    }
}

程序中的new PoolConfig()参数代表使用Pool类的默认配置,192.168.1.105参数代表Redis的IP地址,7777参数代表连接Redis的端口号,5000参数代表在5s之内没有连接到Redis则出现超时异常,accp参数代表Redis的连接密码。

程序运行结果如下。

我是中国人

对redis-cli命令使用--bigkeys参数可以找到大key,以做后续存储的优化,测试如下。

ghy@ghy-VirtualBox:~$ redis-cli -a accp
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> set a aa
OK
127.0.0.1:6379> set b bbb
OK
127.0.0.1:6379> set c cccc
OK
127.0.0.1:6379> set d ddddd
OK
127.0.0.1:6379> 
ghy@ghy-VirtualBox:~$ redis-cli -a accp --bigkeys
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.

# Scanning the entire keyspace to find biggest keys as well as
# average sizes per key type.  You can use -i 0.1 to sleep 0.1 sec
# per 100 SCAN commands (not usually needed).

[00.00%] Biggest string found so far 'd' with 5 bytes

-------- summary -------

Sampled 4 keys in the keyspace!
Total key length in bytes is 4 (avg len 1.00)

Biggest string found 'd' has 5 bytes

0 lists with 0 items (00.00% of keys, avg size 0.00)
0 hashs with 0 fields (00.00% of keys, avg size 0.00)
4 strings with 14 bytes (100.00% of keys, avg size 3.50)
0 streams with 0 entries (00.00% of keys, avg size 0.00)
0 sets with 0 members (00.00% of keys, avg size 0.00)
0 zsets with 0 members (00.00% of keys, avg size 0.00)
ghy@ghy-VirtualBox:~$

导入其他配置文件需要在redis.conf配置文件中使用include,运行结果如图1-66所示。

图1-66 运行结果

由于配置文件采用最后的配置覆盖之前的配置,因此my1.conf配置文件在redis.conf配置文件的最后使用include进行导入,使端口6666覆盖默认的端口6379。


从本章开始主要介绍Redis中的命令。Redis有很多种命令,在开发中常见的命令还是针对常见数据类型的CRUD操作,这也是学习的重点。

另外,全面学习命令还有助于学习Java Client API的使用方法,因为那些Java Client API的使用方法在底层其实还是调用对应Redis中的命令,命令是操作Redis中数据的根源。

Connection类型的命令主要用于处理连接。

使用格式如下。

auth password

该命令用于登录验证。

如果在redis.conf配置文件中开启了requirepass以对Redis设置登录密码,则在每次执行redis-cli命令但并不添加-a参数去连接Redis时,就要使用auth命令进行登录验证,登录成功之后才能执行其他的Redis命令。如果没有登录成功,则执行其他Redis命令时会出现错误信息。

(error) NOAUTH Authentication required.

如果对auth命令指定的密码和redis.conf配置文件中的密码一致,Redis服务器会返回如下信息。

OK

否则,如果密码错误,Redis服务器将返回错误信息。

(error) ERR invalid password

 

注意:由于Redis的高性能特性,其可以在很短的时间内进行大量并行的登录验证,因此建议设置一个复杂的密码,以免被字典式地暴力破解。

 

测试案例如下。

[gaohongyan@localhost ~]$ redis-cli -p 7777
127.0.0.1:7777> keys *
(error) NOAUTH Authentication required.
127.0.0.1:7777> auth abcabcabcac
(error) ERR invalid password
127.0.0.1:7777> auth accp
OK
127.0.0.1:7777> keys *
1) "key1"
2) "username"

除了以更改redis.conf配置文件的方式设置密码以外,还可以直接在客户端中使用config set命令设置密码,更改redis.conf配置文件设置密码的方式如下。

#requirepass accp

添加“#”注释,可以设置Redis无密码。

客户端测试如下。

ghy@ghy-VirtualBox:~$ redis-cli -p 6379 --raw
127.0.0.1:6379> keys *
a
127.0.0.1:6379> get a
aa
127.0.0.1:6379> config set requirepass abc
OK
127.0.0.1:6379> config get requirepass
NOAUTH Authentication required.

127.0.0.1:6379> auth abc
OK
127.0.0.1:6379> config get requirepass
requirepass
abc
127.0.0.1:6379> set a newa
OK
127.0.0.1:6379> get a
newa
127.0.0.1:6379>

现在Redis服务器的密码是abc,重启Redis服务器并执行如下命令。

ghy@ghy-VirtualBox:~$ redis-cli -p 6379 --raw
127.0.0.1:6379> get a
newa
127.0.0.1:6379>

没有经过登录验证也可以执行get命令,说明密码abc并未持久化到redis.conf配置文件中,随着Redis服务器的重启,密码abc丢失了。redis.conf配置文件中还是原始的配置。

这时可以执行如下config rewrite命令,将内存中的配置持久化到redis.conf配置文件中。
127.0.0.1:6379> config set requirepass abc
OK
127.0.0.1:6379> config rewrite
NOAUTH Authentication required.

127.0.0.1:6379> auth abc
OK
127.0.0.1:6379> config rewrite
OK
127.0.0.1:6379>

命令执行后在redis.conf配置文件的最后添加了配置,内容如下。

requirepass "abc"

密码abc被持久化,Redis服务器重启后会使用这个密码作为登录验证。

public class Test1 {
    private static Pool pool = new Pool(new PoolConfig(), "192.168.61.84", 7777);

    public static void main(String[] args) {
          = null;
        try {
             = pool.getResource();
            .auth("accp");
            System.out.println("登录成功!");
            .set("username", "我是中国人");
            String username = .get("username");
            System.out.println(username);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if ( != null) {
                 .close();
            }
        }
    }
}

程序运行结果如下。

登录成功!
我是中国人

程序运行后通过登录验证,然后对数据库成功进行set和get操作。

使用格式如下。

echo message

该命令用于输出特定的消息message。

测试案例如下。

127.0.0.1:6379> echo a b c
ERR wrong number of arguments for 'echo' command

127.0.0.1:6379> echo "a b c"
a b c
127.0.0.1:6379> echo abc
abc
127.0.0.1:6379> echo true
true
127.0.0.1:6379> echo false
false
127.0.0.1:6379> echo 123
123
127.0.0.1:6379> echo null
null
127.0.0.1:6379>
public class Test2 {
    private static Pool pool = new Pool(new PoolConfig(), "192.168.1.105", 7777, 5000, "accp");

    public static void main(String[] args) {
          = null;
        try {
             = pool.getResource();
            String echoString1 = .echo("我是中国人");
            byte[] byteArray = .echo("我是美国人".getBytes());
            System.out.println(echoString1);
            System.out.println(new String(byteArray));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if ( != null) {
                 .close();
            }
        }
    }
}

程序运行结果如下。

我是中国人
我是美国人

使用格式如下。

ping

客户端向Redis服务器发送ping命令,用于测试与Redis服务器的连接是否有效。如果连接到Redis服务器,则会返回pong命令;如果连接不到Redis服务器,则出现如下异常。

Could not connect to Redis at 127.0.0.1:7777: Connection refused

使用ping命令可以实现自定义“心跳”,检测Redis服务器中实例的存活情况。

测试案例如下。

127.0.0.1:7777> ping
pong
public class Test3 {
    private static Pool pool = new Pool(new PoolConfig(), "192.168.1.105", 7777, 5000, "accp");

    public static void main(String[] args) {
          = null;
        try {
             = pool.getResource();
            System.out.println(.ping());
            System.out.println(.ping("你好"));
            System.out.println(new String(.ping("中国").getBytes()));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if ( != null) {
                 .close();
            }
        }
    }
}

程序运行结果如下。

PONG
你好
中国

如果网络断开,则在执行ping命令时会出现异常,示例程序如下。

public class Test4 {
    private static Pool pool = new Pool(new PoolConfig(), "192.168.1.105", 7777, 5000, "accp");

    public static void main(String[] args) {
          = null;
        try {
             = pool.getResource();
            Thread.sleep(10000);
            System.out.println(.ping());
        } catch (Exception e) {
            System.out.println("出现异常!");
            e.printStackTrace();
        } finally {
            if ( != null) {
                 .close();
            }
        }
    }
}

程序运行后在sleep处停止,并在10s内快速销毁Redis服务进程,然后控制台输出如下异常。

出现异常!
redis.clients..exceptions.ConnectionException: Unexpected end of stream.
    at redis.clients..util.RedisInputStream.ensureFill(RedisInputStream.java:202)
    at redis.clients..util.RedisInputStream.readByte(RedisInputStream.java:43)
    at redis.clients..Protocol.process(Protocol.java:155)
    at redis.clients..Protocol.read(Protocol.java:220)
    at redis.clients..Connection.readProtocolWithCheckingBroken(Connection.java:318)
    at redis.clients..Connection.getStatusCodeReply(Connection.java:236)
    at redis.clients..Binary.ping(Binary.java:189)
    at connection.Test4.main(Test4.java:15)

使用格式如下。

quit

该命令用于请求Redis服务器断开与当前客户端的连接。

测试案例如下。

127.0.0.1:7777> quit
[gaohongyan@localhost ~]$
public class Test5 {
    private static Pool pool = new Pool(new PoolConfig(), "192.168.1.105", 7777, 5000, "accp");

    public static void main(String[] args) {
          = null;
        try {
             = pool.getResource();
            .set("username", "我是中国人");
            String username = .get("username");
            System.out.println(username);
            Thread.sleep(20000);
            System.out.println(.quit());
            Thread.sleep(Integer.MAX_VALUE);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if ( != null) {
                 .close();
            }
        }
    }
}

暂时不要先运行Java程序,而是使用如下命令查看连接Redis服务器的客户端数量。

info clients

执行结果如图2-1所示。

图2-1 执行结果

选项connected_clients值为1,代表redis-cli正在连接Redis服务器,这个“1”就代表redis-cli连接。

运行Java程序,然后在20s之内可以使用如下命令。

info clients

查看连接到Redis服务器的客户端数量,如图2-2所示。

选项connected_clients值为2的原因是redis-cli和Java进程同时连接Redis服务器。

在20s过后,.quit()已经被执行,再次执行如下命令。

info clients

连接到Redis服务器的客户端数量变成1,如图2-3所示。

图2-2 查看连接到Redis服务器的客户端数量

图2-3 连接到Redis服务器的客户端数量变成1

由图可知,客户端如果执行.quit()就会断开与Redis服务器的连接,释放连接会增加Redis服务器的利用率,把Redis服务器宝贵有限的连接资源让给其他需要的人。

Redis没有数据库名称,而是使用索引代替。

使用格式如下。

select index

该命令用于选择目标数据库,数据库索引index用数字值指定,以0作为起始索引值,默认使用 0 号数据库。

Redis默认有16个数据库,配置文件如图2-4所示。

图2-4 配置文件

测试案例如下。

127.0.0.1:6379> keys *

127.0.0.1:6379> set a 0
OK
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> set a 1
OK
127.0.0.1:6379[1]> get a
1
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> get a
0
127.0.0.1:6379>
public class Test6 {
    private static Pool pool = new Pool(new PoolConfig(), "192.168.61.84", 7777, 5000, "accp");

    public static void main(String[] args) {
          = null;
        try {
             = pool.getResource();
            {
                .select(0);
                .set("username", "我是中国人0");
                String username = .get("username");
                System.out.println(username);
            }
            {
                .select(10);
                .set("username", "我是中国人10");
                String username = .get("username");
                System.out.println(username);
            }
            {
                .select(0);
                String username = .get("username");
                System.out.println(username);
            }
            {
                .select(10);
                String username = .get("username");
                System.out.println(username);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if ( != null) {
                .close();
            }
        }
    }
}

程序运行结果如下。

我是中国人0
我是中国人10
我是中国人0
我是中国人10

使用格式如下。

swapdb index index

该命令用于交换两个数据库的索引值。

测试案例如下。

127.0.0.1:7777> flushall
OK
127.0.0.1:7777> set username username0
OK
127.0.0.1:7777> get username
"username0"
127.0.0.1:7777> select 1
OK
127.0.0.1:7777[1]> set username username1
OK
127.0.0.1:7777[1]> get username
"username1"
127.0.0.1:7777[1]> swapdb 0 1
OK
127.0.0.1:7777[1]> get username
"username0"
127.0.0.1:7777[1]> select 0
OK
127.0.0.1:7777> get username
"username1"
127.0.0.1:7777>
public class Test7 {
    private static Pool pool = new Pool(new PoolConfig(), "192.168.61.84", 7777, 5000, "accp");

    public static void main(String[] args) {
          = null;
        try {
             = pool.getResource();
            {
                .select(0);
                .set("username", "我是中国人0");
                String username = .get("username");
                System.out.println(username);
            }
            {
                .select(10);
                .set("username", "我是中国人10");
                String username = .get("username");
                System.out.println(username);
            }
            .swapDB(0, 10);
            {
                .select(0);
                String username = .get("username");
                System.out.println(username);
            }
            {
                .select(10);
                String username = .get("username");
                System.out.println(username);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if ( != null) {
                 .close();
            }
        }
    }
}

程序运行结果如下。

我是中国人0
我是中国人10
我是中国人10
我是中国人0

测试程序如下。

public class Test8 {
    private static Pool pool = new Pool(new PoolConfig(), "192.168.1.103", 7777, 5000, "accp");

    public static void main(String[] args) {
        try {
             1 = pool.getResource();
             2 = pool.getResource();
             3 = pool.getResource();
             4 = pool.getResource();
             5 = pool.getResource();

            System.out.println(1.clientList());

            1.close();
            2.close();
            3.close();
            4.close();
            5.close();

            System.out.println(1.clientList());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

clientList()方法的作用是获知有哪些客户端正在连接Redis服务器。

程序运行结果如下。

id=24 addr=192.168.1.104:58412 fd=7 name= age=1 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=32742 obl=0 oll=0 omem=0 events=r cmd=client
id=25 addr=192.168.1.104:58413 fd=8 name= age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=auth
id=26 addr=192.168.1.104:58414 fd=9 name= age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=auth
id=27 addr=192.168.1.104:58415 fd=10 name= age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=auth
id=28 addr=192.168.1.104:58416 fd=11 name= age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=auth

id=24 addr=192.168.1.104:58412 fd=7 name= age=1 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=32742 obl=0 oll=0 omem=0 events=r cmd=client
id=25 addr=192.168.1.104:58413 fd=8 name= age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=auth
id=26 addr=192.168.1.104:58414 fd=9 name= age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=auth
id=27 addr=192.168.1.104:58415 fd=10 name= age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=auth
id=28 addr=192.168.1.104:58416 fd=11 name= age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=auth

虽然使用如下代码关闭了连接,但从输出的结果来看,只是关闭了与Pool类的连接,而Pool类一直以长连接的方式连接到Redis服务器,实现最快速地访问Redis服务器。

    1.close();
    2.close();
    3.close();
    4.close();
    5.close();

Pool类默认允许的最大连接数为8,可以更改配置。

public class Test9 {
    private static Pool pool = null;
    public static void main(String[] args) {
        PoolConfig config = new PoolConfig();
        config.setMaxTotal(1000); //改成连接池中最大连接数为1000
        pool = new Pool(config, "192.168.1.103", 7777, 5000, "accp");
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            pool.getResource();
            System.out.println(i + 1);
        }
    }
}

程序运行后成功创建1000个连接。


相关图书

NoSQL权威指南
NoSQL权威指南
解读NoSQL
解读NoSQL
高可用架构·不一样的数据库(第2期)
高可用架构·不一样的数据库(第2期)

相关文章

相关课程