本文是对Redis基础知识的一个学习总结,共包括如下章节内容:
- Redis是什么
- 安装和部署
- 数据库操作
- Java API
- 小结
一、Redis是什么
Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的Nosql(Key-Value)分布式数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。
Redis最常见的应用是被用作应用系统中的缓存系统,是当前最热门的缓存系统之一。Redis 与其他 key - value 缓存产品相比,有如下特点:
1、Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
2、Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
3、Redis支持数据的备份,即master-slave模式的数据备份。
4、Redis性能极高,其能读的速度是110000次/s,写的速度是81000次/s 。
5、Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务。
6、Redis支持分布式部署,支持大数据量的处理。
二、安装和部署
Redis的官网是https://redis.io,目前最新的稳定版本是5.0.3,下载的压缩包文件是redis-5.0.3.tar.gz。另外Redis的官网还提供了含Redis的Docker镜像的下载。
需要说明的是,Redis项目只正式提供linux下的Redis版本,没有提供windows下的Redis版本,但是Microsoft开放技术小组开发和维护了可在Windows下运行的Redis版本,可以到 https://github.com/MicrosoftArchive/redis/releases 这个地址去下载,不过最新的windows下的Redis版本(最新的是2016.7月发布的)只是基于redis3.2.1,可以看出已经很老了。
本文的介绍是基于 Redis在linux下的运行,使用的版本是最新的5.0.3。使用的linux系统CentOS 7.2。
下面我们来介绍如何在linux进行Redis运行环境搭建。
(一)编译
Redis官方提供下载后的版本是源码包,需要使用make命令进行编译。具体步骤如下:
1、解压redis-5.0.3.tar.gz文件
将下载得到的redis-5.0.3.tar.gzti压缩文件拷贝到想要安装Redis的目录下,执行如下命令,解压到当前目录下。
tar -xvzf redis-5.0.3.tar.gz
这时我们会发现当前目录下多了一个redis-5.0.3目录,这时redis-5.0.3.tar.gz文件不需要了,可以删除。
2、进入解压出来的目录
cd redis-5.0.3
3、执行make命令,编译源码包
make
运行make命令,会看到很多信息输出,不用管它,等待执行结束。最后得到的目录结构如下:
$ cd redis-5.0.3/
$ ls -l
总用量 256
-rw-rw-r-- 1 hadoop hadoop 92434 12月 12 20:25 00-RELEASENOTES
-rw-rw-r-- 1 hadoop hadoop 53 12月 12 20:25 BUGS
-rw-rw-r-- 1 hadoop hadoop 1894 12月 12 20:25 CONTRIBUTING
-rw-rw-r-- 1 hadoop hadoop 1487 12月 12 20:25 COPYING
drwxrwxr-x 6 hadoop hadoop 4096 3月 12 15:42 deps
-rw-rw-r-- 1 hadoop hadoop 11 12月 12 20:25 INSTALL
-rw-rw-r-- 1 hadoop hadoop 151 12月 12 20:25 Makefile
-rw-rw-r-- 1 hadoop hadoop 4223 12月 12 20:25 MANIFESTO
-rw-rw-r-- 1 hadoop hadoop 20555 12月 12 20:25 README.md
-rw-rw-r-- 1 hadoop hadoop 62155 12月 12 20:25 redis.conf
-rwxrwxr-x 1 hadoop hadoop 275 12月 12 20:25 runtest
-rwxrwxr-x 1 hadoop hadoop 280 12月 12 20:25 runtest-cluster
-rwxrwxr-x 1 hadoop hadoop 281 12月 12 20:25 runtest-sentinel
-rw-rw-r-- 1 hadoop hadoop 9710 12月 12 20:25 sentinel.conf
drwxrwxr-x 3 hadoop hadoop 8192 3月 13 11:23 src
drwxrwxr-x 10 hadoop hadoop 4096 12月 12 20:25 tests
drwxrwxr-x 8 hadoop hadoop 4096 12月 12 20:25 utils
编译后的Redis的可执行程序(如启动Redis实例的程序、命令行客户端程序、一些脚本)在redis-5.0.3目录的子目录src下。如果想方便后续的执行,也可以把一些可执行程序从src中拷贝到别的地方,比如新建一个bin目录。
(二)配置
在redis-5.0.3目录下有一个redis.conf配置文件,启动Redis服务时可以指定该配置文件,这样Redis服务的一些参数设置就从该配置文件中获取。如果启动时,不指定配置文件,则使用默认值。可以对redis.conf文件不做任何修改,这样使用默认值启动Redis服务。
可以不需要修改redis.conf文件中的任何默认配置就可以正常启动Redis。
下面介绍一些常用的配置项修改信息:
1、端口号
配置文件默认的配置信息如下
port 6379
6379是Redis实例默认使用的端口。如果需要用别的端口,需要修改这个值。特别是当在一台机器上启动多个redis实例时,每个实例需要有不同的端口。
2、支持Redis客户端远程访问Redis服务器
默认情况下,启动Redis服务后,只允许在服务器上访问Redis服务,可以改成允许远程Redis客户端来连接Redis服务。方法是:
在配置文件中找到
bind 127.0.0.1
这行信息,改为
# bind 127.0.0.1
3、采用后台方式启动Redis服务
默认情况下,启动Redis服务时,是在前台启动的,即一旦启动服务的控制台被关闭,则Redis服务也终止了,可以修改成采用后台方式启动。方法是:
在配置文件中找到
daemonize no
这行信息,改为
daemonize yes
4、设置密码
默认情况下,Redis客户端连接Redis服务器是不需要密码的,可以改成需要密码的方式。方法是:
在配置文件中找到
# requirepass foobared
这行信息,改为
requirepass 需要设置的密码
(三)启动Redis服务
当前目录是redis-5.0.3,执行Redis服务器启动程序,如下面操作:
src/redis-server redis.conf
说明:如果不带redis.conf参数,则使用默认配置值。
可以通过执行如下的操作系统命令来检查Redis是否正常启动:
netstat -nlpt
这时从输出信息中可以查看是否有6379 端口在侦听,有的话说明服务启动成功。
(四)启动Redis命令行客户端
Redis自带了一个命令行客户端可执行程序(文件名为redis-cli),可以用来连接到Redis服务器,然后执行相关操作。
执行客户端程序,启动客户端,如:
src/redis-cli
这样就出现一个交互式命令行界面,可以输入各种命令,如:
$ src/redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> info
# Server
redis_version:5.0.3
redis_git_sha1:00000000
......
其中的ping命令用来测试与服务器是否连接正常,info命令显示Redis服务器和客户端的各种信息,信息很多,上面只是给出了少量信息。
执行exit命令可以退出交互式命令行。
如果我们要用Redis命令行程序连接到远程的Redis服务器,方法如:
src/redis-cli -h 服务器IP地址 -p 6379
(五)停止Redis服务
如果Redis服务是采用前台方式启动,则只需在相应的控制台ctrl+c即可。
如果没有界面可操作,比如Redis服务是采用后台方式启动的,则可以这样停止服务:
方法一:利用redis-cli程序停止服务,在命令行下执行如下命令
src/redis-cli shutdown
这种方式实际是给Redis服务器发送一个停止服务的消息,Redis服务收到此消息后,就会自动停止。
方法二:强制停止
如果采用上面的方式无法停止,可使用操作系统的kill命令强制杀死Redis服务对应的进程。
首先得找到Redis服务对应的进程的进程号,可以执行如下操作系统命令:
ps -ef|grep redis
输出的信息会显示redis服务进程的进程号,然后执行:
kill -9 进程号
这样就强制停止Redis服务,强制停止可能导致正在持久化的信息丢失。所以正常情况下应该采用上一种方式。
三、数据库操作
Redis是key-value格式数据库,其值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。下面我们来介绍如何在命令行下进行数据库的相关操作。
(一)字符串数据
最简单的数据是字符串数据,常见的操作如下:
1、保存数据
语法格式:set key value
set是命令,key和value是要保存数据的键名和字符串值
举例:set mykey good
上面例子的mykey是key名,good是该key对应值。
说明:
1)如果设置的key不存在,则创建新的键值对,如果已经存在,则更新值。
2)如果字符串字符之间有空格,需要引号括起来。如set mykey "hello world"
2、获取数据
语法格式:get key
举例:get mykey
说明:如果指定的key不存在,则返回(nil)信息。
3、删除数据
语法格式:del key
举例:del mykey
说明:如果删除成功,输出 (integer) 1,否则输出(integer) 0
下面是操作示例,如下:
127.0.0.1:6379> set mykey good
OK
127.0.0.1:6379> get mykey
"good"
127.0.0.1:6379> set mykey 12
OK
127.0.0.1:6379> get mykey
"12"
127.0.0.1:6379> del mykey
(integer) 1
127.0.0.1:6379> del mykey
(integer) 0
127.0.0.1:6379> get mykey
(nil)
(二)hash数据
redis支持存储hash数据,也就是value是一个map,hash特别适合用于存储对象。下面介绍一些常见的操作。
1、保存数据
语法格式:hset key field1 value1 [field2 value2 ]
含义:将一对或多对field/value值保存到key对应的hash值中。
举例:hset user id 10 name tom
说明:
1)如果对应的key不存在,则创建一个新的键值对,这个值就是一个hash,该hash的内容就是命令中的一对或多对filed/value。
2)如果对应的key已经存在,但key对应的value不是hash类型,则会用命令中的hash值覆盖该key的值,相当于该key的值变为一个hash类型。
3)如果对应的key已经存在,且key对应的value是hash类型,则就会往该hash值添加或覆盖新的field/value值。
2、获取数据(获取整个Hash值)
语法格式:hgetall key
举例:hgetall user
说明:该命令会返回指定的key对应的hash值,注意如果该key对应的值类型不是hash会报错。
3、获取数据(获取Hash中指定的filed的value)
语法格式:hget key field
举例:hget user id
4、检查hash值中指定的键值对是否存在
语法格式:hexists key field
举例:hexists user name
说明:如果存在,返回(integer) 1,否则返回(integer) 0
5、检查hash值中键值对的数量
语法格式:hlen key
举例:hlen user
说明:如果存在,返回(integer) 1,否则返回(integer) 0
6、删除数据
如果删除整个键值对,使用上面对字符串值操作中的del命令即可。如果只是删除hash值中指定的键值对,则使用如下命令。
语法格式:hdel key field
举例:hdel user id
(三)列表数据
redis支持value值为列表,即一个有序的字符串列表。列表是按照栈的方式操作,即最后插入的元素会被最先获取到。下面介绍一些常见的操作。
1、保存数据
语法格式:lpush key value1 [value2]
举例1:lpush data 12 14
说明:上述命令在redis数据库中插入一个键为data,值是一个列表(包含12,14两个元素)的键值对数据。该命令输出为(integer) 2 ,这个2表示列表中的元素个数。
举例2:lpush data 23 13
在上面例子的基础上往data对应的列表中再插入两个元素
该命令输出为(integer) 4,这个4表示列表中的元素个数。
2、获取数据
举例1:llen data
llen获取列表中的元素个数,在上面命令基础上执行,则输出(integer) 4,这个4表示列表中的元素个数。
举例2:lindex data 0
通过索引获取列表中指定序号的元素,从0开始。0代表最后插入的元素,这里的输出是13
举例3:lrange data 0 3
获取列表指定范围内的元素,第一个数字从最后插入的元素算起。
3、移除并获取元素
举例1:LPOP data
移出并获取列表的第一个元素,这里第一个元素指最后插入的元素
举例2:RPOP data
移除并获取列表最后一个元素
(四)集合数据
redis支持value值为集合(SET),Redis 中的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。下面介绍一些常见的操作。
1、保存数据
举例1:sadd myset hello1 hello2
说明:上面例子的sadd命令插入一个键为myset,值为集合(含hello1,hello2两个元素)的键值对。返回值为(integer) 2,表示列表中有2个元素。
举例2:sadd myset hello3
在上面例子基础上执行上述命令,往已有的集合中添加元素,返回值为(integer) 3,表示列表中有3个元素。
举例3:sadd myset hello1
在上面例子基础上执行上述命令,返回值为(integer) 0,表示添加数据不成功,因为set类型中的数据不允许重复,而前面的操作集合中已经有hello1数据,再次添加数据就不成功了。
2、获取数据
举例1:smembers myset
说明:获取键myset对应的值集合中的所有元素
3、移除数据
举例2:spop myset
说明:随机移除集合中的一个元素,并返回该元素。因为redis集合中的元素是无序的,所有无法按序号指定元素
举例3:srem myset hello1 hello3
说明:移除集合中指定的一个或多个元素,注意这里指定的是元素值,不是序号
(五)有序集合数据
Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。下面介绍一些常见的操作。
1、保存数据
语法格式:zadd key score1 member1 [score2 member2]
举例:zadd myzset 1 hello 2 world
说明:zadd命令有点类似hset命令,集合中的每个元素除指定元素值外(如上面的hello, world),还需为每个元素指定一个分数(1,2)
2、获取数据(集合中元素个数)
语法格式:zcard key
举例:zcard myzset
说明:获取指定key对应的有序集合中元素的个数
3、获取数据
语法格式:zrange myzset start end
说明:zrange 获取指定序号范围内的元素
举例:
zrange myzset 0 0 //获取第1个元素
zrange myzset 0 1 //获取第1个和第2个元素
zrange myzset 0 -1 //获取全部元素
4、移除元素
举例:zrem myzset hello
说明:移除指定的一个或多个元素
上面使用命令对如何使用Redis支持的各种数据类型进行了简单介绍,Redis对各种数据类型操作的命令非常丰富,这里只是介绍了一些最常用和最基本的操作。
四、Java API
在真实的应用场景中,我们大多是通过Redis提供的API来编写程序访问Redis数据库,Redis提供了多种编程语言的API。
下面我们以常见的Java API为例来介绍如何通过编写程序的方式来访问Redis数据库。Jedis是Redis官方首选的Java客户端开发包,在本文中我们使用Jedis来访问Redis数据库数据库。
我们通过maven来自动引入依赖的jar包。先建立一个maven工程,pom文件加入依赖:
<dependency>
<groupId>redis.clients</groupId>
<artifactId><u>jedis</u></artifactId>
<version>2.9.0</version>
</dependency>
在本例子,我们使用的jedis版本是2.9.0。
我们来编写一个最简单的例子,代码如下:
package redisdemo;
import redis.clients.jedis.Jedis;
public class Demo {
public static void main(String[] args) {
Jedis jedis = new Jedis();
jedis.set("mydata", "hello");
String value = jedis.get("mydata");
System.out.println(value);
jedis.close();
}
}
上面代码是一个完整的可执行java程序,代码全部在main方法中。我们先创建Jedis 类的一个实例,没有使用任何设置,表示连接到本地的Redis数据库。然后Jedis 类的set方法插入一个字符串数据,再调用get方法获取插入的键对应的值。
运行程序后,我们通过Redis命令行去执行get mydata,一样可以获取到数据。
如果我们要删除刚才创建的键值对,可以如下代码:
package redisdemo;
import redis.clients.jedis.Jedis;
public class Demo {
public static void main(String[] args) {
Jedis jedis = new Jedis();
jedis.del("mydata");
jedis.close();
}
}
运行程序后,我们通过Redis命令行去执行get mydata,会发现查询不到数据了。
上面只是利用Jedis库来执行最基本的操作,Jedis库提供了丰富的API可以完成各种对Redis数据库的操作,这里不再详细介绍。
五、小结
本文对Redis的基础知识做了介绍,包括单机环境下的安装和部署、如何通过命令行来访问redis数据库,以及如何通过Java API编写程序来访问Redis数据库。
Redis可以用到多种场景下,比如:
1)对于数据处理不复杂的业务场景,可以直接代替传统数据库来作为持久化的数据库。
2)作为应用系统的缓存系统,尤其是在分布式系统中的缓存系统。
本文介绍的是单机环境,在对安全性较高、数据量较大的生产环境下,一般会采用集群的部署方式,要了解Redis的集群部署方式,可查看文档《Redis学习笔记2-集群部署》。