redis的安装和命令的使用(史上最全命令集合)

                                     redis的安装和使用       


1. redis介绍
1.1 什么是NoSQL


NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。目前一些主流的NOSQL

产品:
1.2 NoSQL数据库的分类
1.2.1 键值(Key-Value)存储数据库
相关产品有Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB,主要应用于内容缓存,主要用于处理大量数据的高访问负载。
1.2.2 列存储数据库
相关产品有Cassandra, HBase, Riak,典型应用于分布式的文件系统。
1.2.3 文档型数据库
相关产品有CouchDB、MongoDB,典型应用于Web应用,可以突破传统关系型数据库的结构限制,存储数据更为灵活。
1.2.4 图形(Graph)数据库
相关数据库有Neo4J、InfoGrid、Infinite Graph,典型应用于社交网络,存储数据采用图结构利用图结构相关算法。
1.3 什么是redis


1.4 redis历史发展
2008年,意大利的一家创业公司Merzia推出了一款基于MySQL的网站实时统计系统LLOOGG,然而没过多久该公司的创始人 Salvatore Sanfilippo便 对MySQL的性能感到失望,于是他决定亲自为LLOOGG量身定做一个数据库,并于2009年开发完成,这个数据库就是Redis。 不过Salvatore Sanfilippo
并不满足只将Redis用于LLOOGG这一款产品,而是希望更多的人使用它,于是在同一年Salvatore Sanfilippo将Redis开源发布,并开始和Redis的另一名主要的代码贡献者Pieter Noordhuis一起继续着Redis的开发,直到今天。
Salvatore Sanfilippo自己也没有想到,短短的几年时间,Redis就拥有了庞大的用户群体。Hacker News在2012年发布了一份数据库的使用情况调查,结果显示有近12%的公司在使用Redis。国内如新浪微博、街旁网、知乎网,国外如GitHub、Stack Overflow、Flickr等都是Redis的用户。
VMware公司从2010年开始赞助Redis的开发, Salvatore Sanfilippo和Pieter Noordhuis也分别在3月和5月加入VMware,全职开发Redis。完全免费
1.5 redis的应用场景
Redis广泛应用于缓存,布式集群架构中的session分离,聊天室的在线好友列表,任务队列,应用排行榜,网站访问统计,数据过期处理等场景。
2. redis的安装


2.1 redis安装环境
redis是C语言开发,建议在linux上运行,本教程使用Centos6.4作为安装环境。
安装redis需要先将官网下载的源码进行编译,编译依赖gcc环境,如果没有gcc环境,需要安装gcc:yum install gcc-c++。
2.2 redis安装
我们使用的Redis版本为redis3.0版本,首先可以从官网下载Redis压缩包http://download.redis.io/releases/redis-3.0.0.tar.gz,然后将下载的redis上传到虚拟机的/usr/local目录下。


接下来解压Redis压缩包,使用命令:tar -zxvf redis-3.0.7.tar.gz


进入解压后的目录进行编译和安装,编译使用命令make,安装使用命令make install。安装成功后运行Redis服务,如果出现以下界面,则Redis安装成功,启动命令:redis-server。


Redis安装之后,我们在/usr/local/bin下可以发现编译之后的Redis执行文件。


2.3 redis的启动
2.3.1 前端模式启动
直接运行redis-server将以前端模式启动,前端模式启动的缺点是占用终端,同时ssh命令窗口关闭则redis-server程序结束,所以不推荐使用此方法。
2.3.2 后端模式启动
修改redis.conf配置文件, 将daemonize 设置yes 以后即可以后端模式来启动Redis。


修改之后用当前修改后的配置文件来启动Redis服务器。


此时我们可以使用命令的方式查看服务是否已经启动。


我们发现Redis服务已经启动,默认使用6379端口。
2.3.3 启动多个redis进程
启动多个Redis服务,一般采用定义多个对应的配置文件的方式来启动不同配置的Redis服务,同时需要分别修改每一个Redis服务器启动的端口号。这里我们启动两个Redis服务器,分别使用6379和6380端口。
首先我们创建两个目录。


在两个目录中定义redis的配置文件,这里我们将redis默认的配置文件拷贝过来,并修改对应的端口号,然后分别启动两个Redis服务。


2.4 redis的停止
要停止正在运行的Redis服务,可以采用Linux命令的方式直接杀掉Redis服务的进程,也可以使用Redis客户端想服务器发送shutdown指令来关闭Redis服务器。


2.5 使用redis客户端
在redis的安装目录中有redis的客户端,即redis-cli(Redis Command Line Interface),它是Redis自带的基于命令行的Redis客户端。
2.5.1 连接Redis服务器
使用redis-cli命令即可连接默认的本机6379端口的Redis服务器。如下图表示连接成功。


如果希望远程连接其他主机或者其他端口的Redis服务器,可以加上以下的参数,使用-h设置远程主机的ip,使用-p设置远程主机的端口号。


2.5.2 向Redis服务器发送命令
redis-cli连上redis服务后,可以在命令行向Redis服务器发送命令。
1.5.1.1 ping命令
Redis提供了PING命令来测试客户端与Redis的连接是否正常,如果连接正常会收到回复PONG。


1.5.1.2 set/get命令
使用set和get可以向redis设置数据、获取数据。


1.5.1.3 del命令
del命令用来删除指定key的内容。


1.5.1.4 keys*命令
keys*命令用来查看当前redis数据库中存在的key的名称。


1.5.1.5 flushdb命令
flushdb命令用来清空当前数据库中的所有数据。


2.6 Redis多数据库
一个Redis数据库可以包括多个数据库,客户端可以指定连接某个redis实例的哪个数据库,就好比一个mysql中创建多个数据库,客户端连接时指定连接哪个数据库。一个redis实例默认提供16个数据库,这由启动的配置文件中指定,下标从0到15,客户端默认连接第0号数据库,也可以通过select选择连接哪个数据库,不同数据库中的数据不能共享。


需要注意的问题是,如果我们使用flushall命令清空某一个库中的数据时,其他库中的数据也会被清空,因此,在我们不同的业务访问Redis服务器时应该选择不同的Redis服务器,而不是同一个服务器内部的不同的数据库。


3. Jedis的使用
3.1 Jedis介绍
Redis不仅是使用命令来操作,现在基本上主流的语言都有客户端支持,比如java、C、C#、C++、php、Node.js、Go等。
在官方网站里列一些Java的客户端,有Jedis、Redisson、Jredis、JDBC-Redis、等其中官方推荐使用Jedis和Redisson。 在企业中用的最多的就是Jedis,下面我们就重点学习下Jedis。
3.2 通过jedis连接redis
3.2.1 添加jar包
要使用Jedis需要加入Jedis对应的jar包。我们使用maven来构建工程,因此直接使用jedis的jar包依赖坐标即可。

 <dependency>
 <groupId>redis.clients</groupId> 
 <artifactId>jedis</artifactId>
 <version>2.7.0</version>
 </dependency>


Maven会自动在工程中添加jedis需要依赖的jar包。


3.2.2 单实例连接Redis
通过创建单实例jedis对象连接redis服务,直接创建Jedis对象即可,如下
代码:

package com.igeek.redis_jedis_01; 
import org.junit.Test; 
import redis.clients.jedis.Jedis; 
public class AppTest{ 
@Test 
public void testJedisSingle() { 
//创建Jedis对象,传递两个参数:第一个host为redis服务器的名称,第二个为redis服务器的端口号
 Jedis jedis = new Jedis("192.168.5.128", 6379); 
 //进行设值操作 
jedis.set("username","zhangsan");
 //从redis中取值 
String username = jedis.get("username");
 System.out.println("username:"+username);
 }
}


3.2.3 使用连接池连接Redis
通过单实例连接redis不能对redis连接进行共享,可以使用连接池对redis连接进行共享,提高资源利用率,使用jedisPool连接redis服务,如下代码:

package com.igeek.redis_jedis_01; 
import org.junit.Test; 
import redis.clients.jedis.Jedis;
 import redis.clients.jedis.JedisPool; 
import redis.clients.jedis.JedisPoolConfig;
 public class AppTest{ 
@Test
public void testJedisPool(){ 
//创建JedisPool连接池配置 
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); 
//设置连接池的最大连接数 
jedisPoolConfig.setMaxTotal(20); 
//设置连接池的最大连接空闲数 
jedisPoolConfig.setMaxIdle(2); 
//设置redis服务器的主机 
String host = "192.168.5.128"; 
//设置redis服务器的端口 
int port = 6379; 
//创建JedisPool连接池对象 
JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port);
 //获取Jedis对象
 Jedis jedis = jedisPool.getResource(); 
//存入数据 
jedis.set("info", "message"); 
//获取数据 
String info = jedis.get("info"); 
System.out.println("info:"+info); 
//关闭资源 
jedisPool.close(); 
} 
}


4. redis的数据类型
4.1 String类型
redis中没有使用C语言的字符串表示,而是自定义一个数据结构叫SDS(simple dynamic string)即简单动态字符串。redis的字符串是二进制安全的,
存入什么数据取出的还是什么数据。
String类型的的常用命令有:
4.1.1 赋值命令
redis中赋值操作使用set命令,语法 set key value。
范例:向redis中插入数据,键为name,值为zhangsan。


如果希望一次性插入多条数据,可以使用mset命令,语法mset key1 value1 key2 value2 …
范例:一次性向redis中插入以下数据,id为1,age为 20。


4.1.2 取值命令
redis中进行取值操作使用get命令,语法:get key。
范例:获取键为name的数据的值


需要注意的是,如果通过get命令获取数据时,给定的键不存在,则返回(nil),表示查询结果为空。
如果希望一次性从redis中获取多个键对应的数据的值,可以使用mget命令,语法:mget key1 key2 …
范例:获取redis中id,name,age的数据的值。


我们也可以使用getset命令,在获取对应键的数据的同时,为该键指定新的值。语法:getset key newValue。
范例:获取name对应的名称,并将名称的值改为lisi。


4.1.3 删除命令
在Redis中删除数据使用del命令,语法:del key。
范例:删除id对应的数据的值。


如果需要直接清空该库中所有数据,可以使用flushdb命令。
范例:清空当前数据库中的数据。


如果要清空所有库中的所有数据使用flushall命令。
范例:清理redis所有库中的所有数据。


4.1.4 数值递增
当存储的字符串是整数时,Redis提供了一个实用的命令incr,其作用是让当前键值递增,并返回递增后的值。语法:incr key。
范例:向数据库中插入数据num初始值为1,然后自增加1。


以上的自增表示每次加1,如果需要按照指定的数据来进行增长,可以使用incrby命令,语法:incrby key increment。
范例:使用incrby命令将num的数据值加10。


4.1.5 数值递减
当需要对数据进行递减操作时,使用decr命令,语法:decr key。
范例:将num对应数据的值递减1。


如果希望递减指定的数值,可以使用decrby,语法:decrby key decrement。
范例:将num对应数据的值减10.


4.1.6 追加数据
在Redis中可以使用append命令向指定数据的末尾追加内容,语法:append key value。
范例:向info数据的末尾添加内容。


注意:在插入数据时,字符串的双引号默认可以省略,但是如果字符串中包含空格的情况,需要加上双引号,否则空格会被忽略。
4.1.7 获取长度
使用strlen命令可以返回指定键对应的值的长度,如果键不存在则返回0。语法:strlen key。
范例:获取info对应的数据的长度。


4.2 hash类型
hash叫散列类型,它提供了字段和字段值的映射。字段值只能是字符串类型,不支持散列类型、集合类型等其它类型。
hash类型的的常用命令有:
4.2.1 赋值命令
向hash中插入获设置数据没使用hset命令,语法:hset key field value。
范例:向redis中插入user的name属性值为songjiang。


如果希望从redis中一次性设置多个字段的值,可以使用hmset,语法:hmset key field1 value1 field2 value2 …
范例:向redis中插入user的id和age属性。


4.2.2 取值命令
从hash中获取数据使用hget命令,语法:hget key field。
范例:获取user的name属性的值。


使用hmget可以一次性获取多个字段的值。语法:hmget key field1 field2 field3 …
范例:获取user的id,name,age字段的值。


可以使用hgetall命令,或者指定键的所有字段和字段的值。语法:hgetall key。
使用HKEYS和HVALS命令可以分别用来获取指定键的所有键和所有值。
范例:获取user的所有键和所有值。


4.2.3 判断字段是否存在
判断字段是否存在使用HEXISTS命令,如果存在则返回1,如果不存在则返回0 ,语法:HEXISTS key field
范例:判断user是否存在。


4.2.4 获取字段数量
获取字段数量使用HLEN命令,如果键不存在则返回0,语法HLEN key。
范例:获取指定键的数据中键的数量。


4.2.5 删除命令
要删除一个或多个字段,使用hdel命令,语法:HDEL key field [field ...]。
范例:删除user的id字段的值。


范例:删除user的name和age字段。


4.2.6 增加数字
如果hash中的字段存储的值为数值类型,可以进行自增操作。语法:HINCRBY key field increment。
范例:将user的age字段的值增加1.


4.3 list类型
列表类型(list)可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段。
列表类型内部是使用双向链表(double linked list)实现的,所以向列表两端添加元素的时间复杂度为0(1),获取越接近两端的元素速度就越快。这意味着即使是一个有几千万个元素的列表,获取头部或尾部的10条记录也是极快的。
list类型的的常用命令有:
4.3.1 添加数据
Redis列表采用双向链表实现,因此在插入数据时可以从两端分别操作,向列表左边增加元素使用lpush命令,向列表右边增加元素使用rpush命令。
范例:向列表中插入数据


4.3.2 查看列表
LRANGE命令是列表类型最常用的命令之一,获取列表中的某一片段,将返回start、stop之间的所有元素(包含两端的元素),索引从0开始。索引可以是负数,如:“-1”代表最后边的一个元素。
范例:获取列表nums和nums2中的数据


从以上获取的数据结构来看,我们发现从列表的左侧插入数据,在列表中数据以倒叙存放,从列表的右侧插入数据则是正序存放。
4.3.3 获取数据
在列表中可以使用lpop和rpop分别列表的左侧和右侧弹出一个数据,该数据会首先返回,然后再从原列表中删除。
范例:弹出nums的左侧数据。


范例:弹出nums的右侧数据。


4.3.4 获取列表中元素的个数
使用LLEN命令可以获取列表中元素的个数。范例:LLEN key
范例:获取nums2列表中元素的个数。


4.3.5 删除列表中指定的值
LREM命令会删除列表中前count个值为value的元素,返回实际删除的元素个数。根据count值的不同,该命令的执行方式会有所不同:
 当count>0时, LREM会从列表左边开始删除。
 当count<0时, LREM会从列表后边开始删除。
 当count=0时, LREM删除所有值为value的元素。
范例:删除nums中的4元素


4.3.6 获得/设置指定索引的元素值 获得或者设置指定索引的元素值分别使用lindex和lset命令。
范例:获取nums列表中索引2对应的数据


范例:将nums中索引2对应的数据改为x\


4.3.7 只保留列表指定片段
List中使用ltrim命令对列表中的数据进行截取操作,只保留指定数据片段。语法:ltrim key start stop。
范例:截取nums列表中索引从1开始到3的数据


4.3.8 向列表中插入元素
向列表中指定位置插入元素可以使用linsert命令,语法:LINSERT key BEFORE|AFTER pivot value。
范例:向nums列表中的x元素后面插入元素y


4.3.9 将元素从一个列表转移到另一个列表中
使用RPOPLPUSH命令可以将元素从一个列表转移到另一个列表中。语法:RPOPLPUSH source destination。
范例:将元素从一个列表转移到另一个列表中


4.4 set类型
集合类型的常用操作是向集合中加入或删除元素、判断某个元素是否存在等,由于集合类型的Redis内部是使用值为空的散列表实现,所有这些操作的时间复杂度都为0(1)。 Redis还提供了多个集合之间的交集、并集、差集的运算。
set类型的的常用命令有:
4.4.1 增加/删除元素
集合中添加数据使用sadd命令,语法sadd key member [member…].
范例:向set集合中添加数据


4.4.2 获得集合中的所有元素
获取集合中所有元素使用SMEMBERS命令,语法:SMEMBERS key
范例:获取set集合中的所有元素


4.4.3 集合的差集运算
属于A并且不属于B的元素构成的集合,使用命令SDIFF,语法:SDIFF key [key ...]
范例:集合的差集


4.4.4 集合的交集运算
属于A并且也属于B的元素构成的集合,使用命令SINTER,语法:SINTER key [key ...]
范例:集合的交集


4.4.5 集合的并集运算
属于A并且或者属于B的元素构成的集合,使用命令SUNION,语法:SUNION key [key ...]
范例:集合的并集


4.4.6 获得集合中元素的个数 获得集合中元素的个数,使用SCARD命令,如果集合不存在则返回0,语法:SCARD key
范例:获取集合set中元素的个数


4.4.7 从集合中弹出一个元素
从集合中弹出一个元素使用spop命令,语法:spop key
范例:从set集合中弹出一个元素


4.5 sorted set类型
在集合类型的基础上有序集合类型为集合中的每个元素都关联一个分数,这
使得我们不仅可以完成插入、删除和判断元素是否存在在集合中,还能够获得分数最高或最低的前N个元素、获取指定分数范围内的元素等与分数有关的操作。
在某些方面有序集合和列表类型有些相似。
1、二者都是有序的。
2、二者都可以获得某一范围的元素。
但是,二者有着很大区别:
1、列表类型是通过链表实现的,获取靠近两端的数据速度极快,而当元素增多后,访问中间数据的速度会变慢。
2、有序集合类型使用散列表实现,所有即使读取位于中间部分的数据也很快。
3、列表中不能简单的调整某个元素的位置,但是有序集合可以(通过更改分数实现)
4、有序集合要比列表类型更耗内存。
sorted set类型的的常用命令有:
4.5.1 增加元素
向有序集合中加入一个元素和该元素的分数,如果该元素已经存在则会用新的分数替换原有的分数。返回值是新加入到集合中的元素个数,不包含之前已经存在的元素。语法:ZADD key score member [score member ...]
范例:向有序集合中添加数据


4.5.2 获得排名在某个范围的元素列表
获得排名在某个范围的元素列表使用zrange命令,语法:ZRANGE key start stop [WITHSCORES]
范例:获取score中的元素


以上是根据分数进行升序排列,如果要进行降序排列,我们使用命令ZREVRANGE。
范例:降序获取score中的元素


4.5.3 删除元素
移除有序集key中的一个或多个成员使用命令ZREM,不存在的成员将被忽略。语法:ZREM key member [member ...]
范例:移除score中zhangsan元素


4.5.4 获得指定分数范围的元素
获得指定分数范围的元素使用ZRANGEBYSCORE命令,语法:ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
范例:获取score中分数在60 – 80分之间的数据元素。


4.5.5 增加某个元素的分数,返回值是更改后的分数
增加某个元素的分数,返回值是更改后的分数,使用命令ZINCRBY,语法:ZINCRBY key increment member
范例:给lisi加4分


4.5.6 获得集合中元素的数量
获取集合中元素的数量使用ZCARD命令,语法:ZCARD key。
范例:获取score集合中元素的个数


4.5.7 获得指定分数范围内的元素个数
获得指定分数范围内的元素个数使用命令zcount,语法:ZCOUNT key min max。
范例:获取score中分数在70-90之间的元素个数


4.5.8 按照排名范围删除元素
按照排名范围删除元素使用命令ZREMRANGEBYRANK,语法:ZREMRANGEBYRANK key start stop
范例:删除score中排名前两位的元素


4.5.9 按照分数范围删除元素
按照分数范围删除元素使用命令ZREMRANGEBYSCORE,语法:ZREMRANGEBYSCORE key start stop
范例:删除score中分数在60 -80之间的元素


4.5.10 获取元素的排名
获取元素的排名使用zrank命令,语法:ZRANK key member
范例:查看score中qianqi的排名


以上是升序后的排名,如果要使用倒序排名使用命令ZREVRANK。
范例:查看score中qianqi的倒序排名


5. redis的其他命令
5.1 设置key的生存时间
Redis在实际使用过程中更多的用作缓存,然而缓存的数据一般都是需要设置生存时间的,即:到期后数据销毁。

EXPIRE key seconds 设置key的生存时间(单位:秒)key在多少秒后会自动删除
TTL key 查看key生于的生存时间
PERSIST key 清除生存时间
PEXPIRE key milliseconds 生存时间设置单位为:毫秒


范例:key生存时间的设置


5.2 返回满足给定pattern 的所有key
Redis中可以使用pattern来获取键的名称。
范例:查看所有以user开头的键


5.3 重命名key
重命名key使用命令rename,语法:rename name newName
范例:将名为username的键改为user_name


5.4 返回值的类型
使用type命令可以返回指定键的值的类型,语法:type key。
范例:获取user_name的数据的类型


5.5 返回当前数据库中key 的数目
返回当前数据库中key的数目使用dbsize命令。
范例:获取当前数据库中key的数目


5.6 获取服务器的信息和统计
获取服务器的信息和统计使用info命令。
范例:获取服务器信息

127.0.0.1:6379> info
# Server
redis_version:3.0.7
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:9310b523e663e7ad
redis_mode:standalone
os:Linux 2.6.32-431.el6.i686 i686
arch_bits:32
multiplexing_api:epoll
gcc_version:4.4.7
process_id:1296
run_id:89f7fd18598e38523ccd3dd89b144a7013f3bef3
tcp_port:6379
uptime_in_seconds:28310
uptime_in_days:0
hz:10
lru_clock:16746523
config_file:/usr/local/6379/./redis.conf
# Clients
connected_clients:2
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
# Memory
used_memory:658112
used_memory_human:642.69K
used_memory_rss:1904640
used_memory_peak:658328
used_memory_peak_human:642.90K
used_memory_lua:24576
mem_fragmentation_ratio:2.89
mem_allocator:jemalloc-3.6.0
# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1509918442
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
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
# Stats
total_connections_received:5
total_commands_processed:287
instantaneous_ops_per_sec:0
total_net_input_bytes:10452
total_net_output_bytes:13479
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:1
evicted_keys:0
keyspace_hits:98
keyspace_misses:10
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:1469
migrate_cached_sockets:0
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
# CPU
used_cpu_sys:28.60
used_cpu_user:15.06
used_cpu_sys_children:0.03
used_cpu_user_children:0.01
# Cluster
cluster_enabled:0
# Keyspace
db0:keys=4,expires=0,avg_ttl=0


此时我们发现使用info获取的数据信息很丰富,如果只需要获取某一个方便的信息,可以使用info加上需要的信息的名称。
范例:获取数据库的CPU信息。


5.7 退出连接
6. redis的持久化
Redis的高性能是由于其将所有数据都存储在了内存中,为了使Redis在重启之后仍能保证数据不丢失,需要将数据从内存中同步到硬盘中,这一过程就是持久化。
Redis支持两种方式的持久化,一种是RDB方式,一种是AOF方式。可以单独使用其中一种或将二者结合使用。
6.1 RDB持久化
RDB方式的持久化是通过快照(snapshotting)完成的,当符合一定条件时Redis会自动将内存中的数据进行快照并持久化到硬盘。
RDB是Redis默认采用的持久化方式,在redis.conf配置文件中默认有此下配置:

save 900 1
save 300 10
save 60 10000


save 开头的一行就是持久化配置,可以配置多个条件(每行配置一个条件),每个条件之间是“或”的关系,“save 900 1”表示15分钟(900秒钟)内至少1个键被更改则进行快照,“save 300 10”表示5分钟(300秒)内至少10个键被更改则进行快照。
Redis启动后会读取RDB快照文件,将数据从硬盘载入到内存。根据数据量
大小与结构和服务器性能不同,这个时间也不同。通常将记录一千万个字符串类型键、大小为1GB的快照文件载入到内存中需要花费20~30秒钟。
如果开启了RDB,Redis默认会在启动当前服务的目录自动创建数据文件。通过RDB方式实现持久化,一旦Redis异常退出,就会丢失最后一次快照以后更改的所有数据。这就需要开发者根据具体的应用场合,通过组合设置自动快照条件的方式来将可能发生的数据损失控制在能够接受的范围。如果数据很重要以至于无法承受任何损失,则可以考虑使用AOF方式进行持久化。
6.2 AOF持久化
默认情况下Redis没有开启AOF(append only file)方式的持久化,可以通过appendonly参数开启:appendonly yes
开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的,默认的文件名是appendonly.aof,可以通过appendfilename参数修改:appendfilename appendonly.aof
7. redis的主从复制
7.1 什么是主从复制
持久化保证了即使redis服务重启也会丢失数据,因为redis服务重启后会将硬盘上持久化的数据恢复到内存中,但是当redis服务器的硬盘损坏了可能会导致数据丢失,如果通过redis的主从复制机制就可以避免这种单点故障。


说明:
 主redis中的数据有两个副本(replication)即从redis1和从redis2,即使一台redis服务器宕机其它两台redis服务也可以继续提供服务。
 主redis中的数据和从redis上的数据保持实时同步,当主redis写入数据时通过主从复制机制会复制到两个从redis服务上。
 只有一个主redis,可以有多个从redis。
 主从复制不会阻塞master,在同步数据时,master 可以继续处理client 请求
7.2 主从复制实现
在Redis从服务器上添加其对应的主服务器的信息,修改从redis服务器上的redis.conf文件,添加slaveof 主redis服务器的ip 和端口号。


启动主从服务器之后即完成了对Redis主从复制的配置。
 

单服务代码使用:

package com.igeek.jedis;

import java.util.List;

import org.junit.Before;
import org.junit.Test;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * @author www.igeehome.com
 * 
 * TODO
 *
 * 2018年11月14日下午7:27:22
 */
public class JedisTest {
	Jedis jedis = null;
	
	JedisPool pool = null;
	
	
	@Before
	public void before(){
		//jedis = new Jedis("192.168.229.112", 6379);
		
		//pool = new JedisPool("192.168.229.112", 6379); //默认配置
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxIdle(20);
		config.setMaxTotal(50);
		pool = new JedisPool(config, "192.168.229.112", 6379);
		jedis = pool.getResource();
	}
	
	@Test
	public void testOther(){
		boolean flag = jedis.exists("jlist1");
		Long incr = jedis.incr("k1");
		
		jedis.expire("jlist", 50);
		Long ttl = jedis.ttl("jlist");
	}
	
	
	@Test
	public void testList1(){
		List<String> lrange = jedis.lrange("jlist", 0, -1);
		System.out.println(lrange);
	}
	
	@Test
	public void testList(){
		jedis.lpush("jlist", "1","2","3");
	}
	
	@Test
	public void testHash(){
		jedis.hset("user1", "name", "zhangsan");
		jedis.hset("user1", "age", "18");
		jedis.hset("user1", "gender", "1");
	}
	
	@Test
	public void testGet(){
		Jedis jedis = new Jedis("192.168.229.112", 6379);
		String name = jedis.get("stuname");
		System.out.println(name);
	}
	

	@Test
	public void testConnRedis(){
		Jedis jedis = new Jedis("192.168.229.112", 6379);
		jedis.set("jedisK1", "testjedis");
	}
}

集群代码使用:

package com.igeek.jedis;

import java.util.HashSet;
import java.util.Set;

import org.junit.Test;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

/**
 * @author www.igeehome.com
 * 
 * TODO
 *
 * 2018年11月14日下午8:47:46
 */
public class JedisClusterTest {

	@Test
	public void testJedisCluster(){
		Set<HostAndPort> nodes = new HashSet<HostAndPort>();
		nodes.add(new HostAndPort("192.168.229.112", 7001));
		nodes.add(new HostAndPort("192.168.229.112", 7002));
		nodes.add(new HostAndPort("192.168.229.112", 7003));
		nodes.add(new HostAndPort("192.168.229.112", 7004));
		nodes.add(new HostAndPort("192.168.229.112", 7005));
		nodes.add(new HostAndPort("192.168.229.112", 7006));
		//连接集群
		JedisCluster cluster = new JedisCluster(nodes );
		
		String set = cluster.set("uname", "zhangsan");
		System.out.println(set);
	}
}

猜你喜欢

转载自blog.csdn.net/qq_15204179/article/details/84065968