Redis

1、redis的介绍
a)什么是NoSql
b)什么是redis
2、redis的安装配置(重点)
3、redis的客户端
a)redis自带的客户端
b)图形界面的客户端
c)Jedis客户端
4、redis的数据类型(重点)
a)string
b)hash
c)list
d)set
e)sortedset
5、keys命令
6、redis的持久化
a)rdb方式
b)aof方式
7、redis的主从复制
8、redis的集群(重点)
9、jedis连接集群(重点)

2redis的介绍
2.1什么是NoSql
为了解决高并发、高可用、高可扩展而产生的一套数据库解决方案。

Nosql not-only sql 非关系型数据库。NoSql只是关系型数据库的一个良好补充,不能替换。
2.2NoSql的分类
键值(Key-Value)存储数据库
相关产品: Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB
典型应用: 内容缓存,主要用于处理大量数据的高访问负载。
数据模型: 一系列键值对
优势: 快速查询
劣势: 存储的数据缺少结构化

列存储数据库
相关产品:Cassandra, HBase, Riak
典型应用:分布式的文件系统
数据模型:以列簇式存储,将同一列数据存在一起
优势:查找速度快,可扩展性强,更容易进行分布式扩展
劣势:功能相对局限
文档型数据库
相关产品:CouchDB、MongoDB
典型应用:Web应用(与Key-Value类似,Value是结构化的)
数据模型: 一系列键值对
优势:数据结构要求不严格
劣势: 查询性能不高,而且缺乏统一的查询语法
图形(Graph)数据库
相关数据库:Neo4J、InfoGrid、Infinite Graph
典型应用:社交网络
数据模型:图结构
优势:利用图结构相关算法。
劣势:需要对整个图做计算才能得出结果,不容易做分布式的集群方案。

2.3什么是redis
Redis是使用c语言开发的一套高性能的键值对数据库。
Redis提供了几种数据类型来存储键值对数据,具体类型如下:

a)string
b)hash
c)list
d)set
e)sortedset
2.4redis历史发展
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。
2.5 redis的应用场景
缓存(数据查询、短连接、新闻内容、商品内容等等)。(最多使用)
分布式集群架构中的session分离。
聊天室的在线好友列表。
任务队列。(秒杀、抢购、12306等等)
应用排行榜。
网站访问统计。
数据过期处理(可以精确到毫秒)

3Redis的安装配置
3.1Redis的安装环境
Redis是使用c语言开发的,需要将redis安装到linux系统。
3.2下载redis
官网地址:http://redis.io/
下载地址:http://download.redis.io/releases/redis-3.0.0.tar.gz
在这里插入图片描述

3.3Redis安装
第一步:需要安装VMware,然后安装centOS(参考linux教程)
第二步:安装c语言环境(一般centos系统自带c语言环境,可以省略该步骤)
Yum install gcc-c++
第三步:将redis的源码包上传到linux系统
在这里插入图片描述

第四步:解压缩redis源码包
[root@redis0810 ~]# tar -zxf redis-3.0.0.tar.gz
第五步:进入到redis-3.0.0目录,执行make命令,编译redis源码
[root@redis0810 redis-3.0.0]# make
第六步:安装redis
在这里插入图片描述
3.4Redis启动
3.4.1前端启动
执行命令:[root@redis0810 bin]# ./redis-server
在这里插入图片描述
前端启动的关闭:ctrl+c

3.4.2后端启动
第一步:将redis源码包中的redis.conf文件拷贝到redis0180/bin目录下
[root@redis0810 redis-3.0.0]# cp redis.conf /usr/local/redis0810/bin/

第二步:修改redis.conf,将daemonize 修改为yes
在这里插入图片描述

第三步:启动redis
[root@redis0810 redis-3.0.0]#./redis-server redis.conf

4Redis客户端
4.1Redis自带的客户端
执行命令,则可以打开客户端:[root@redis0810 bin]# ./redis-cli -h 127.0.0.1 -p 6379

也可以通过以下命令,打开客户端,默认主机地址是127.0.0.1,默认端口 6379
[root@redis0810 bin]# ./redis-cli
在这里插入图片描述

4.2图形界面的redis客户端
在这里插入图片描述

点击以上可执行文件进行安装。
在这里插入图片描述
在这里插入图片描述

出现以上问题,则说明redis服务器的6379端口没有在防火墙配置文件中开发。

需要修改防火墙规则:

[root@redis0810 ~]# vim /etc/sysconfig/iptables
在这里插入图片描述

重启防火墙:
[root@redis0810 ~]# service iptables restart
iptables:清除防火墙规则: [确定]
iptables:将链设置为政策 ACCEPT:filter [确定]
iptables:正在卸载模块: [确定]
iptables:应用防火墙规则: [确定]
[root@redis0810 ~]#

默认redis安装之后,有16个数据库实例,如果想修改,则需要修改redis.conf文件
在这里插入图片描述

切换数据库实例的命令:
Select 15
在这里插入图片描述

4.3Jedis客户端
4.3.1Jedis介绍
Redis不仅是使用命令来操作,现在基本上主流的语言都有客户端支持,比如java、C、C#、C++、php、Node.js、Go等。
在官方网站里列一些Java的客户端,有Jedis、Redisson、Jredis、JDBC-Redis、等其中官方推荐使用Jedis和Redisson。 在企业中用的最多的就是Jedis,下面我们就重点学习下Jedis。
Jedis同样也是托管在github上,地址:https://github.com/xetorthio/jedis

4.3.2添加jar包
在这里插入图片描述
4.3.3创建单实例连接
在这里插入图片描述

4.3.4创建jedis连接池进行连接
在这里插入图片描述

5Redis的数据类型
5.1String字符型
5.1.1命令
5.1.1.1赋值
语法:SET key value
127.0.0.1:6379> set test 123
OK

5.1.1.2取值
语法:GET key
127.0.0.1:6379> get test
"123“

5.1.1.3取值并赋值
语法:GETSET key value
127.0.0.1:6379> getset s2 222
“111”
127.0.0.1:6379> get s2
“222”

5.1.1.4删除
语法:DEL key
127.0.0.1:6379> del test
(integer) 1

5.1.1.5数值增减
递增数字
当存储的字符串是整数时,Redis提供了一个实用的命令INCR,其作用是让当前键值递增,并返回递增后的值。

语法:INCR key
127.0.0.1:6379> incr num
(integer) 1
127.0.0.1:6379> incr num
(integer) 2
127.0.0.1:6379> incr num
(integer) 3

增加指定的整数
语法:INCRBY key increment
127.0.0.1:6379> incrby num 2
(integer) 5
127.0.0.1:6379> incrby num 2
(integer) 7
127.0.0.1:6379> incrby num 2
(integer) 9

递减数值
语法:DECR key
127.0.0.1:6379> decr num
(integer) 9
127.0.0.1:6379> decr num
(integer) 8

减少指定的整数
语法:DECRBY key decrement
127.0.0.1:6379> decr num
(integer) 6
127.0.0.1:6379> decr num
(integer) 5
127.0.0.1:6379> decrby num 3
(integer) 2
127.0.0.1:6379> decrby num 3
(integer) -1

5.1.1.6其它命令(自学)
5.1.1.6.1向尾部追加值
APPEND的作用是向键值的末尾追加value。如果键不存在则将该键的值设置为value,即相当于 SET key value。返回值是追加后字符串的总长度。

语法:APPEND key value
127.0.0.1:6379> set str hello
OK
127.0.0.1:6379> append str " world!"
(integer) 12
127.0.0.1:6379> get str
“hello world!”

5.1.1.6.2获取字符串长度
STRLEN命令返回键值的长度,如果键不存在则返回0。

语法:STRLEN key
127.0.0.1:6379> strlen str
(integer) 0
127.0.0.1:6379> set str hello
OK
127.0.0.1:6379> strlen str
(integer) 5

5.1.1.6.3同时设置/获取多个键值
语法:
MSET key value [key value …]
MGET key [key …]

127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> get k1
“v1”
127.0.0.1:6379> mget k1 k3

  1. “v1”
  2. “v3”

5.1.2应用
5.1.2.1自增主键
商品编号、订单号采用string的递增数字特性生成。

定义商品编号key:items:id
192.168.101.3:7003> INCR items:id
(integer) 2
192.168.101.3:7003> INCR items:id
(integer) 3

5.2Hash散列类型
5.2.1使用string的问题
假设有User对象以JSON序列化的形式存储到Redis中,User对象有id,username、password、age、name等属性,存储的过程如下:
保存、更新:
User对象 json(string) redis
如果在业务上只是更新age属性,其他的属性并不做更新我应该怎么做呢? 如果仍然采用上边的方法在传输、处理时会造成资源浪费,下边讲的hash可以很好的解决这个问题。

5.2.2redis hash介绍
hash叫散列类型,它提供了字段和字段值的映射。字段值只能是字符串类型,不支持散列类型、集合类型等其它类型。如下:
在这里插入图片描述

5.2.3命令
5.2.3.1赋值
HSET命令不区分插入和更新操作,当执行插入操作时HSET命令返回1,当执行更新操作时返回0。

一次只能设置一个字段值
语法:HSET key field value
127.0.0.1:6379> hset user username zhangsan
(integer) 1

一次可以设置多个字段值
语法:HMSET key field value [field value …]
127.0.0.1:6379> hmset user age 20 username lisi
OK

当字段不存在时赋值,类似HSET,区别在于如果字段存在,该命令不执行任何操作
语法:HSETNX key field value
127.0.0.1:6379> hsetnx user age 30 如果user中没有age字段则设置age值为30,否则不做任何操作
(integer) 0

5.2.3.2取值
一次只能获取一个字段值
语法:HGET key field
127.0.0.1:6379> hget user username
"zhangsan“

一次可以获取多个字段值
语法:HMGET key field [field …]
127.0.0.1:6379> hmget user age username

  1. “20”
  2. “lisi”

获取所有字段值
语法:HGETALL key
127.0.0.1:6379> hgetall user

  1. “age”
  2. “20”
  3. “username”
  4. “lisi”

5.2.3.3删除字段
可以删除一个或多个字段,返回值是被删除的字段个数

语法:HDEL key field [field …]
127.0.0.1:6379> hdel user age
(integer) 1
127.0.0.1:6379> hdel user age name
(integer) 0
127.0.0.1:6379> hdel user age username
(integer) 1

5.2.3.4增加数字
语法:HINCRBY key field increment
127.0.0.1:6379> hincrby user age 2 将用户的年龄加2
(integer) 22
127.0.0.1:6379> hget user age 获取用户的年龄
"22“

5.2.3.5其它命令(自学)
5.2.3.5.1判断字段是否存在
语法:HEXISTS key field
127.0.0.1:6379> hexists user age 查看user中是否有age字段
(integer) 1
127.0.0.1:6379> hexists user name 查看user中是否有name字段
(integer) 0

5.2.3.5.2只获取字段名或字段值
语法:
HKEYS key
HVALS key
127.0.0.1:6379> hmset user age 20 name lisi
OK
127.0.0.1:6379> hkeys user

  1. “age”
  2. “name”
    127.0.0.1:6379> hvals user
  3. “20”
  4. “lisi”

5.2.3.5.3获取字段数量
语法:HLEN key
127.0.0.1:6379> hlen user
(integer) 2

5.2.4应用
5.2.4.1存储商品信息
商品字段
【商品id、商品名称、商品描述、商品库存、商品好评】

定义商品信息的key
商品1001的信息在 Redis中的key为:[items:1001]

存储商品信息
192.168.101.3:7003> HMSET items:1001 id 3 name apple price 999.9
OK

获取商品信息
192.168.101.3:7003> HGET items:1001 id
“3”
192.168.101.3:7003> HGETALL items:1001

  1. “id”
  2. “3”
  3. “name”
  4. “apple”
  5. “price”
  6. “999.9”

5.3List列表类型
5.3.1ArrayList与LinkedList的区别
ArrayList使用数组方式存储数据,所以根据索引查询数据速度快,而新增或者删除元素时需要设计到位移操作,所以比较慢。
LinkedList使用双向链表方式存储数据,每个元素都记录前后元素的指针,所以插入、删除数据时只是更改前后元素的指针指向即可,速度非常快。然后通过下标查询元素时需要从头开始索引,所以比较慢,但是如果查询前几个元素或后几个元素速度比较快。
在这里插入图片描述
在这里插入图片描述

5.3.2redis list介绍
列表类型(list)可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段。
列表类型内部是使用双向链表(double linked list)实现的,所以向列表两端添加元素的时间复杂度为0(1),获取越接近两端的元素速度就越快。这意味着即使是一个有几千万个元素的列表,获取头部或尾部的10条记录也是极快的。
5.3.3命令
5.3.3.1向列表两端增加元素
向列表左边增加元素
语法:LPUSH key value [value …]
127.0.0.1:6379> lpush list:1 1 2 3
(integer) 3

向列表右边增加元素
语法:RPUSH key value [value …]
127.0.0.1:6379> rpush list:1 4 5 6
(integer) 3

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

语法:LRANGE key start stop
127.0.0.1:6379> lrange list:1 0 2

  1. “2”
  2. “1”
  3. “4”

5.3.3.3从列表两端弹出元素
LPOP命令从列表左边弹出一个元素,会分两步完成:
第一步是将列表左边的元素从列表中移除
第二步是返回被移除的元素值。

语法:
LPOP key
RPOP key
127.0.0.1:6379> lpop list:1
"3“
127.0.0.1:6379> rpop list:1
"6“

5.3.3.4获取列表中元素的个数
语法:LLEN key
127.0.0.1:6379> llen list:1
(integer) 2

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

语法:LREM key count value

5.3.3.5.2获得/设置指定索引的元素值
获得指定索引的元素值
语法:LINDEX key index
127.0.0.1:6379> lindex l:list 2
“1”

设置指定索引的元素值
语法:LSET key index value
127.0.0.1:6379> lset l:list 2 2
OK
127.0.0.1:6379> lrange l:list 0 -1

  1. “6”
  2. “5”
  3. “2”
  4. “2”

5.3.3.5.3只保留列表指定片段
指定范围和LRANGE一致

语法:LTRIM key start stop
127.0.0.1:6379> lrange l:list 0 -1

  1. “6”
  2. “5”
  3. “0”
  4. “2”
    127.0.0.1:6379> ltrim l:list 0 2
    OK
    127.0.0.1:6379> lrange l:list 0 -1
  5. “6”
  6. “5”
  7. “0”

5.3.3.5.4向列表中插入元素
该命令首先会在列表中从左到右查找值为pivot的元素,然后根据第二个参数是BEFORE还是AFTER来决定将value插入到该元素的前面还是后面。

语法:LINSERT key BEFORE|AFTER pivot value
127.0.0.1:6379> lrange list 0 -1

  1. “3”
  2. “2”
  3. “1”
    127.0.0.1:6379> linsert list after 3 4
    (integer) 4
    127.0.0.1:6379> lrange list 0 -1
  4. “3”
  5. “4”
  6. “2”
  7. “1”

5.3.3.5.5将元素从一个列表转移到另一个列表中
语法:RPOPLPUSH source destination
127.0.0.1:6379> rpoplpush list newlist
“1”
127.0.0.1:6379> lrange newlist 0 -1

  1. “1”
    127.0.0.1:6379> lrange list 0 -1
  2. “3”
  3. “4”
  4. “2”

5.3.4应用
5.3.4.1商品评论列表
思路:
在Redis中创建商品评论列表
用户发布商品评论,将评论信息转成json存储到list中。
用户在页面查询评论列表,从redis中取出json数据展示到页面。

定义商品评论列表key:
商品编号为1001的商品评论key【items: comment:1001】
192.168.101.3:7001> LPUSH items:comment:1001 ‘{“id”:1,“name”:“商品不错,很好!!”,“date”:1430295077289}’

5.4Set集合类型
Set集合中的数据是无序且不重复的。

5.4.1命令
5.4.1.1增加/删除元素
语法:SADD key member [member …]
127.0.0.1:6379> sadd set a b c
(integer) 3
127.0.0.1:6379> sadd set a
(integer) 0

语法:SREM key member [member …]
127.0.0.1:6379> srem set c d
(integer) 1

5.4.1.2获得集合中的所有元素
语法:SMEMBERS key
127.0.0.1:6379> smembers set

  1. “b”
  2. "a”

5.4.1.3判断元素是否在集合中
语法:SISMEMBER key member
127.0.0.1:6379> sismember set a
(integer) 1
127.0.0.1:6379> sismember set h
(integer) 0

5.4.2运算命令

5.4.2.1集合的差集运算 A-B
属于A并且不属于B的元素构成的集合。
在这里插入图片描述
语法:SDIFF key [key …]
127.0.0.1:6379> sadd setA 1 2 3
(integer) 3
127.0.0.1:6379> sadd setB 2 3 4
(integer) 3
127.0.0.1:6379> sdiff setA setB

  1. “1”
    127.0.0.1:6379> sdiff setB setA
  2. “4”

5.4.2.2集合的交集运算 A ∩ B
属于A且属于B的元素构成的集合。
在这里插入图片描述
语法:SINTER key [key …]
127.0.0.1:6379> sinter setA setB

  1. “2”
  2. “3”

5.4.2.3集合的并集运算 A ∪ B
属于A或者属于B的元素构成的集合
在这里插入图片描述

语法:SUNION key [key …]
127.0.0.1:6379> sunion setA setB

  1. “1”
  2. “2”
  3. “3”
  4. “4”

5.4.3其它命令(自学)
5.4.3.1获得集合中元素的个数
语法:SCARD key
127.0.0.1:6379> smembers setA

  1. “1”
  2. “2”
  3. “3”
    127.0.0.1:6379> scard setA
    (integer) 3

5.4.3.2从集合中弹出一个元素
注意:由于集合是无序的,所有SPOP命令会从集合中随机选择一个元素弹出

语法:SPOP key
127.0.0.1:6379> spop setA
"1“

5.5Sortedset(zset)
Sortedset可以通过分数来实现排序,它里面的元素不能重复。它可以类似于list类型,获取某一片段的数值。

5.5.1命令

5.5.1.1增加元素
向有序集合中加入一个元素和该元素的分数,如果该元素已经存在则会用新的分数替换原有的分数。返回值是新加入到集合中的元素个数,不包含之前已经存在的元素。

语法:ZADD key score member [score member …]
127.0.0.1:6379> zadd scoreboard 80 zhangsan 89 lisi 94 wangwu
(integer) 3
127.0.0.1:6379> zadd scoreboard 97 lisi
(integer) 0

5.5.1.2获取元素的分数
语法:ZSCORE key member
127.0.0.1:6379> zscore scoreboard lisi
“97”

5.5.1.3删除元素
移除有序集key中的一个或多个成员,不存在的成员将被忽略。
当key存在但不是有序集类型时,返回一个错误。

语法:ZREM key member [member …]
127.0.0.1:6379> zrem scoreboard lisi
(integer) 1

5.5.1.4获得排名在某个范围的元素列表
获得排名在某个范围的元素列表
按照元素分数从小到大的顺序返回索引从start到stop之间的所有元素(包含两端的元素)

语法:ZRANGE key start stop [WITHSCORES]
127.0.0.1:6379> zrange scoreboard 0 2

  1. “zhangsan”
  2. “wangwu”
  3. "lisi“

按照元素分数从大到小的顺序返回索引从start到stop之间的所有元素(包含两端的元素)

语法:ZREVRANGE key start stop [WITHSCORES]
127.0.0.1:6379> zrevrange scoreboard 0 2

  1. " lisi "
  2. “wangwu”
  3. " zhangsan “

如果需要获得元素的分数的可以在命令尾部加上WITHSCORES参数
127.0.0.1:6379> zrange scoreboard 0 1 WITHSCORES

  1. “zhangsan”
  2. “80”
  3. “wangwu”
  4. “94”

5.5.1.5其它命令(自学)
5.5.1.5.1获得指定分数范围的元素
语法:ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
127.0.0.1:6379> ZRANGEBYSCORE scoreboard 90 97 WITHSCORES

  1. “wangwu”
  2. “94”
  3. “lisi”
  4. “97”
    127.0.0.1:6379> ZRANGEBYSCORE scoreboard 70 100 limit 1 2
  5. “wangwu”
  6. “lisi”

5.5.1.5.2增加某个元素的分数
返回值是更改后的分数

语法:ZINCRBY key increment member
127.0.0.1:6379> ZINCRBY scoreboard 4 lisi
"101“

5.5.1.5.3获得集合中元素的数量
语法:ZCARD key
127.0.0.1:6379> ZCARD scoreboard
(integer) 3

5.5.1.5.4获得指定分数范围内的元素个数
语法:ZCOUNT key min max
127.0.0.1:6379> ZCOUNT scoreboard 80 90
(integer) 1

5.5.1.5.5按照排名范围删除元素
语法:ZREMRANGEBYRANK key start stop
127.0.0.1:6379> ZREMRANGEBYRANK scoreboard 0 1
(integer) 2
127.0.0.1:6379> ZRANGE scoreboard 0 -1

  1. “lisi”
    5.5.1.5.6按照分数范围删除元素
    语法:ZREMRANGEBYSCORE key min max
    127.0.0.1:6379> zadd scoreboard 84 zhangsan
    (integer) 1
    127.0.0.1:6379> ZREMRANGEBYSCORE scoreboard 80 100
    (integer) 1

5.5.1.5.7获取元素的排名
从小到大
语法:ZRANK key member
127.0.0.1:6379> ZRANK scoreboard lisi
(integer) 0

从大到小
语法:ZREVRANK key member
127.0.0.1:6379> ZREVRANK scoreboard zhangsan
(integer) 1

5.5.2应用
5.5.2.1商品销售排行榜
需求:根据商品销售量对商品进行排行显示
思路:定义商品销售排行榜(sorted set集合),Key为items:sellsort,分数为商品销售量。

写入商品销售量:
商品编号1001的销量是9,商品编号1002的销量是10
192.168.101.3:7007> ZADD items:sellsort 9 1001 10 1002

商品编号1001的销量加1
192.168.101.3:7001> ZINCRBY items:sellsort 1 1001

商品销量前10名:
192.168.101.3:7001> ZRANGE items:sellsort 0 9 withscores

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

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

例子:
192.168.101.3:7002> set test 1 设置test的值为1
OK
192.168.101.3:7002> get test 获取test的值
“1”
192.168.101.3:7002> EXPIRE test 5 设置test的生存时间为5秒
(integer) 1
192.168.101.3:7002> TTL test 查看test的生于生成时间还有1秒删除
(integer) 1
192.168.101.3:7002> TTL test
(integer) -2
192.168.101.3:7002> get test 获取test的值,已经删除
(nil)

6.2其它命令(自学)

6.2.1keys
返回满足给定pattern 的所有key
redis 127.0.0.1:6379> keys mylist*

  1. “mylist”
  2. “mylist5”
  3. “mylist6”
  4. “mylist7”
  5. “mylist8”

6.2.2exists
确认一个key 是否存在
示例:从结果来看,数据库中不存在HongWan 这个key,但是age 这个key 是存在的
redis 127.0.0.1:6379> exists HongWan
(integer) 0
redis 127.0.0.1:6379> exists age
(integer) 1
redis 127.0.0.1:6379>

6.2.3del
删除一个key
redis 127.0.0.1:6379> del age
(integer) 1
redis 127.0.0.1:6379> exists age
(integer) 0

6.2.4rename
重命名key
示例:age 成功的被我们改名为age_new 了
redis 127.0.0.1:6379[1]> keys *

  1. “age”
    redis 127.0.0.1:6379[1]> rename age age_new
    OK
    redis 127.0.0.1:6379[1]> keys *
  2. “age_new”
    redis 127.0.0.1:6379[1]>

6.2.5type
返回值的类型
示例:这个方法可以非常简单的判断出值的类型
redis 127.0.0.1:6379> type addr
string
redis 127.0.0.1:6379> type myzset2
zset
redis 127.0.0.1:6379> type mylist
list
redis 127.0.0.1:6379>

7redis的持久化
redis的持久化有两种方案:rdb方式、aof方式
7.1rdb方式
redis默认的持久化方案就是rdb方式。Rdb方式是通过一些命令redis服务器,多久持久化一次。

在redis.conf文件中,了解以下信息:

Dir:生成的持久化文件存储的目录

Dbfilename:存储的rdb文件的名称
在这里插入图片描述

7.1.1问题总结
通过RDB方式实现持久化,一旦Redis异常退出,就会丢失最后一次快照以后更改的所有数据。这就需要开发者根据具体的应用场合,通过组合设置自动快照条件的方式来将可能发生的数据损失控制在能够接受的范围。
如果数据很重要以至于无法承受任何损失,则可以考虑使用AOF方式进行持久化。

7.2Aof方式
Redis默认不使用aof方式进行持久化,需要手动开启aof方式

修改redis.conf文件,将appendonly 改为 yes
在这里插入图片描述

Redis服务器启动时会去持久化文件中加载数据。

如果只有rdb方式时,只会去dump.rdb文件中加载数据
如果配合aof方式时,会去appendonlyaof文件中加载数据

8Redis的主从复制
8.1什么是主从复制
持久化保证了即使redis服务重启也不会丢失数据,因为redis服务重启后会将硬盘上持久化的数据恢复到内存中,但是当redis服务器的硬盘损坏了可能会导致数据丢失,如果通过redis的主从复制机制就可以避免这种单点故障,如下图:
在这里插入图片描述
8.2主机的配置
无需多余配置
8.3从机的配置

第一步:复制一个从机

[root@redis0810 redis0810]# cp bin/ bin2 -r
[root@redis0810 redis0810]# ll
总用量 8
drwxr-xr-x. 2 root root 4096 12月 2 22:56 bin
drwxr-xr-x. 2 root root 4096 12月 2 23:04 bin2

第二步:修改从机的redis.conf,将slaveof ip port设置为主机的ip和端口
在这里插入图片描述
第三步:修改从机的redis.conf中port为6380
在这里插入图片描述
第四步:测试主从复制

进入6379服务器
在这里插入图片描述

进入6380服务器
在这里插入图片描述

结论:
只添加6379中的数据,同时会同步到6380服务器中。
在6380(从机)中,不能进行写操作,它是只读的。

[root@redis0810 bin]# ./redis-cli -p 6380
127.0.0.1:6380> get s3
“333”
127.0.0.1:6380> set s4 44
(error) READONLY You can’t write against a read only slave.
9Redis的集群
9.1redis-cluster架构图
在这里插入图片描述

架构细节:
(1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.
(2)Client可以通过集群中的任何一个节点来连接上集群。
(3)在redis集群中,使用16384个槽来存储数据。Redis会根据存储的key进行rcr算法,得到一个结果,然后根据该结果对16384,进行取余,余数找到对应的槽的下标,然后存储到该槽中。

示例如下:
在这里插入图片描述
9.2redis-cluster投票:容错
在这里插入图片描述

(1)集群中所有master参与投票,如果半数以上master节点与其中一个master节点通信超过(cluster-node-timeout),认为该master节点挂掉.
(2):什么时候整个集群不可用(cluster_state:fail)?
如果集群任意master挂掉,且当前master没有slave,则集群进入fail状态。也可以理解成集群的[0-16383]slot映射不完全时进入fail状态。
如果集群超过半数以上master挂掉,无论是否有slave,集群进入fail状态。

9.3Redis集群的搭建
redis集群管理工具redis-trib.rb依赖ruby环境,首先需要安装ruby环境。

第一步:安装ruby环境
[root@redis0810 ~]# yum install ruby
[root@redis0810 ~]# yum install rubygems

第二步:下载并上传redis-3.0.0.gem文件到linux系统

第三步:执行ruby和redis的接口
[root@redis0810 ~]# gem install redis-3.0.0.gem

第四步:将redis-trib.rb文件复制到redis0810/目录下
在这里插入图片描述

第五步:创建3台主机3台从机
集群环境最少需要3台主机。

这6台机器的端口号分别:
7001-7006

[root@redis0810 redis0810]# mkdir rediscluster
[root@redis0810 redis0810]# ll
总用量 60
drwxr-xr-x. 2 root root 4096 12月 2 23:22 bin
drwxr-xr-x. 2 root root 4096 12月 2 23:22 bin2
drwxr-xr-x. 2 root root 4096 12月 2 23:55 rediscluster
-rwxr-xr-x. 1 root root 48141 12月 2 23:53 redis-trib.rb
[root@redis0810 redis0810]# cp bin rediscluster/7001 -r
[root@redis0810 redis0810]# cd rediscluster/
[root@redis0810 rediscluster]# ll
总用量 4
drwxr-xr-x. 2 root root 4096 12月 2 23:55 7001
[root@redis0810 rediscluster]# cd 7001/
[root@redis0810 7001]# ll
总用量 13900
-rw-r–r--. 1 root root 106 12月 2 23:55 appendonly.aof
-rw-r–r--. 1 root root 35 12月 2 23:55 dump.rdb
-rwxr-xr-x. 1 root root 4167902 12月 2 23:55 redis-benchmark
-rwxr-xr-x. 1 root root 16459 12月 2 23:55 redis-check-aof
-rwxr-xr-x. 1 root root 37691 12月 2 23:55 redis-check-dump
-rwxr-xr-x. 1 root root 4256668 12月 2 23:55 redis-cli
-rw-r–r--. 1 root root 41405 12月 2 23:55 redis.conf
lrwxrwxrwx. 1 root root 12 12月 2 23:55 redis-sentinel -> redis-server
-rwxr-xr-x. 1 root root 5686505 12月 2 23:55 redis-server
[root@redis0810 7001]# rm -rf appendonly.aof
[root@redis0810 7001]# rm -rf dump.rdb

将7001目录进行复制,创建成6个文件夹
在这里插入图片描述
第六步:修改6台机器的端口
在这里插入图片描述
第七步:修改cluster-enabled 为 yes
在这里插入图片描述

第八步:启动6台机器

创建一个all.sh脚本,批量启动
[root@redis0810 rediscluster]# vim all.sh
cd 7001
./redis-server redis.conf
cd …
cd 7002
./redis-server redis.conf
cd …
cd 7003
./redis-server redis.conf
cd …
cd 7004
./redis-server redis.conf
cd …
cd 7005
./redis-server redis.conf
cd …
cd 7006
./redis-server redis.conf
cd …

修改all.sh的权限
[root@redis0810 rediscluster]# chmod a+x all.sh
[root@redis0810 rediscluster]# ll
总用量 28
drwxr-xr-x. 2 root root 4096 12月 3 00:01 7001
drwxr-xr-x. 2 root root 4096 12月 3 00:03 7002
drwxr-xr-x. 2 root root 4096 12月 3 00:03 7003
drwxr-xr-x. 2 root root 4096 12月 3 00:03 7004
drwxr-xr-x. 2 root root 4096 12月 3 00:03 7005
drwxr-xr-x. 2 root root 4096 12月 3 00:03 7006
-rwxr-xr-x. 1 root root 240 12月 3 00:06 all.sh

第九步:执行创建集群的命令

[root@redis0810 src]# ./redis-trib.rb create --replicas 1 192.168.242.134:7001 192.168.242.134:7002 192.168.242.134:7003 192.168.242.134:7004 192.168.242.134:7005 192.168.242.134:7006

Creating cluster
Connecting to node 192.168.242.134:7001: OK
Connecting to node 192.168.242.134:7002: OK
Connecting to node 192.168.242.134:7003: OK
Connecting to node 192.168.242.134:7004: OK
Connecting to node 192.168.242.134:7005: OK
Connecting to node 192.168.242.134:7006: OK

Performing hash slots allocation on 6 nodes…
Using 3 masters:
192.168.242.134:7001
192.168.242.134:7002
192.168.242.134:7003
Adding replica 192.168.242.134:7004 to 192.168.242.134:7001
Adding replica 192.168.242.134:7005 to 192.168.242.134:7002
Adding replica 192.168.242.134:7006 to 192.168.242.134:7003
M: f1095be274de6fa9e220d5788c4a9b6954bea485 192.168.242.134:7001
slots:0-5460 (5461 slots) master
M: c0eb9a8896867aecb8a96cf113140a8506977fa6 192.168.242.134:7002
slots:5461-10922 (5462 slots) master
M: 6403ee3ba96f1058c6c9bb7d8b5b6cc63c532978 192.168.242.134:7003
slots:10923-16383 (5461 slots) master
S: 212a816288ed29c8b9dbe73aaff0c81a6c81abfe 192.168.242.134:7004
replicates f1095be274de6fa9e220d5788c4a9b6954bea485
S: 3e92294c91a0bc619b236cb84372e3dfea6ba536 192.168.242.134:7005
replicates c0eb9a8896867aecb8a96cf113140a8506977fa6
S: aa614ec868467ae57d6ebd627b9a21a3048cb0ce 192.168.242.134:7006
replicates 6403ee3ba96f1058c6c9bb7d8b5b6cc63c532978
Can I set the above configuration? (type ‘yes’ to accept): yes

Nodes configuration updated
Assign a different config epoch to each node
Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join…

Performing Cluster Check (using node 192.168.242.134:7001)
M: f1095be274de6fa9e220d5788c4a9b6954bea485 192.168.242.134:7001
slots:0-5460 (5461 slots) master
M: c0eb9a8896867aecb8a96cf113140a8506977fa6 192.168.242.134:7002
slots:5461-10922 (5462 slots) master
M: 6403ee3ba96f1058c6c9bb7d8b5b6cc63c532978 192.168.242.134:7003
slots:10923-16383 (5461 slots) master
M: 212a816288ed29c8b9dbe73aaff0c81a6c81abfe 192.168.242.134:7004
slots: (0 slots) master
replicates f1095be274de6fa9e220d5788c4a9b6954bea485
M: 3e92294c91a0bc619b236cb84372e3dfea6ba536 192.168.242.134:7005
slots: (0 slots) master
replicates c0eb9a8896867aecb8a96cf113140a8506977fa6
M: aa614ec868467ae57d6ebd627b9a21a3048cb0ce 192.168.242.134:7006
slots: (0 slots) master
replicates 6403ee3ba96f1058c6c9bb7d8b5b6cc63c532978
[OK] All nodes agree about slots configuration.

Check for open slots…
Check slots coverage…
[OK] All 16384 slots covered.
[root@redis0810 src]#

9.4连接redis集群
连接集群,需要加上-c。
[root@redis0810 bin]# ./redis-cli -h 192.168.242.134 -p 7001 –c
192.168.242.134:7001> set s1 111
-> Redirected to slot [15224] located at 192.168.242.134:7003
OK
192.168.242.134:7003> get s1
“111”
192.168.242.134:7003> set s2 222
-> Redirected to slot [2843] located at 192.168.242.134:7001
OK
192.168.242.134:7001> set s3 333
-> Redirected to slot [6970] located at 192.168.242.134:7002
OK
192.168.242.134:7002>

9.5查看集群的命令
Cluster info 查看集群信息
Cluster nodes 查看集群节点

192.168.242.134:7002> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:2
cluster_stats_messages_sent:863
cluster_stats_messages_received:863
192.168.242.134:7002> cluster nodes
3e92294c91a0bc619b236cb84372e3dfea6ba536 192.168.242.134:7005 slave c0eb9a8896867aecb8a96cf113140a8506977fa6 0 1449073149660 5 connected
aa614ec868467ae57d6ebd627b9a21a3048cb0ce 192.168.242.134:7006 slave 6403ee3ba96f1058c6c9bb7d8b5b6cc63c532978 0 1449073150668 6 connected
f1095be274de6fa9e220d5788c4a9b6954bea485 192.168.242.134:7001 master - 0 1449073148654 1 connected 0-5460
212a816288ed29c8b9dbe73aaff0c81a6c81abfe 192.168.242.134:7004 slave f1095be274de6fa9e220d5788c4a9b6954bea485 0 1449073147646 4 connected
6403ee3ba96f1058c6c9bb7d8b5b6cc63c532978 192.168.242.134:7003 master - 0 1449073143613 3 connected 10923-16383
c0eb9a8896867aecb8a96cf113140a8506977fa6 192.168.242.134:7002 myself,master - 0 0 2 connected 5461-10922
192.168.242.134:7002>

10Jedis连接集群
10.1开启防火墙
在redis服务器中修改防火墙规则,将7001-7006端口添加到规则内。
[root@redis0810 src]# vim /etc/sysconfig/iptables
在这里插入图片描述
重启防火墙
[root@redis0810 src]# service iptables restart
iptables:清除防火墙规则: [确定]
iptables:将链设置为政策 ACCEPT:filter [确定]
iptables:正在卸载模块: [确定]
iptables:应用防火墙规则: [确定]
[root@redis0810 src]#

10.2代码
在这里插入图片描述

10.3使用spring
配置applicationContext.xml

测试代码

private ApplicationContext applicationContext;
@Before
public void init() {
applicationContext = new ClassPathXmlApplicationContext(
“classpath:applicationContext.xml”);
}

// redis集群
@Test
public void testJedisCluster() {
	JedisCluster jedisCluster = (JedisCluster) applicationContext
			.getBean("jedisCluster");

	jedisCluster.set("name", "zhangsan");
	String value = jedisCluster.get("name");
	System.out.println(value);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值