1.了解NoSql
NoSQL最常见的解释是“non-relational”, “Not Only SQL”也被很多人接受。NoSQL仅仅是一个概念,泛指非关系 型的数据库,区别于关系数据库,它们不保证关系数据的ACID特性。
NoSql数据库的优势:
(1) 易扩展
(2)大数据量,高性能
(3)灵活的数据模型
(4) 高可用
2.Redis介绍
2.1什么是Redis
全称:REmote DIctionary Server(远程字典服务器)。是完全开源免费的,用C语言编写的, 遵守BCD协议。是 一个高性能的(key/value)分布式内存数据库,
Redis 与其他 key - value 缓存产品有以下三个特点
(1) Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用
(2) Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储
(3) Redis支持数据的备份,即master-slave(主从)模式的数据备份
2.2 Redis优势
(1) 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
(2) 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
(3) 原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
(4) 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性
(5) 采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不 用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;
(6) 使用多路I/O复用模型,非阻塞IO;
2.3 Redis应用场景
(1) 缓存(数据查询,短连接,新闻内容,商品内容等),使用最多
(2) 聊天室在线好友列表
(3) 任务队列(秒杀,抢购,12306等)
(4) 应用排行榜
(5) 网站访问统计
(6) 数据过期处理(可以精确到毫秒)
(7) 分布式集群架构中的session问题
3.Linux下安装Redis
Redis的后端启动:[root@localhost redis]# ./bin/redis-server ./redis.conf
Redis的停止:[root@localhost redis]# ./bin/redis-cli shutdown
客户端访问redis:./redis-cli -h ip地址 -p 端口号
退出客户端: quit
第三方工具(redis-desktop-manager)操作redis
4.Redis数据结构
Redis是一种基于内存的数据库,并且提供一定的持久化功能,它是一种键值(key-value)数据库,使用 key 作为 索引找到当前缓存的数据,并且返回给程序调用者。
当前的 Redis 支持 6 种数据类型,它们分别是字符串(String)、列表(List)、集合(set)、哈希结构 (hash)、有序集合(zset)和基数(HyperLogLog)
5.Redis常用指令
5.1 String 类型
赋值语法:SET key value
取值语法: GET key
127.0.0.1:6379> set k1 zhangsan
OK
127.0.0.1:6379> get k1
"zhangsan"
设置多个键语法: MSET key value [key value …]
获取多个键值语法: MGET key [key …]
127.0.0.1:6379> mset k2 lisi k3 wangwu
OK
127.0.0.1:6379> mget k2 k3
1) "lisi"
2) "wangwu"
删除语法:DEL key
127.0.0.1:6379> del k3
(integer) 1
127.0.0.1:6379> get k3
(nil)
5.2 字符串数字的递增与递减
递增数字语法: INCR key
递减数值语法: DECR key
增加指定的整数语法: INCRBY key increment
减少指定的整数 语法:DECRBY key decrement
5.3 Hash散列(了解)
hash叫散列类型,它提供了字段和字段值的映射。字段值只能是字符串类型,不支持散列类型、集合类型等其它类 型。相当于是对象格式的存储
赋值语法: HSET key field value
值语法: HGET key field
设置多个字段语法: HMSET key field value [field value ...]
取多个值语法: HMGET key field [field ...]
获取所有字段值语法:HGETALL key
删除字段语法:HDEL key field [field ...]
5.4 队列List
Redis的list是采用来链表来存储,双向链表存储数据,特点:增删快、查询慢(Linkedlist).这个队列是有序的。
向列表左边增加元素: LPUSH key value [value ...]
从列表左边弹出元素: LPOP key(临时存储,弹出后,从队列中清除)
向列表右边增加元素 : RPUSH key value [value ...]
从列表右边弹出元素: RPOP key
获取列表中元素的个数: LLEN key
查看列表语法:LRANGE key start stop
将返回start、stop之间的所有元素(包含两端的元素),索引从0开始,可以是负数,如:“-1”代表最后的一个元 素。
临时存储。先进先出。使用双向链表:
1,左边进,右边去
2,右边进,左边去。
5.5 Set集合
Set集合类型:无序、不可重复
增加元素语法:SADD key member [member ...]
获得集合中的所有元素 : smembers key
删除元素语法: SREM key member [member ...]
判断元素是否在集合中: SISMEMBER key member
5.6 Zset有序集合(了解)
Sortedset又叫zset,是有序集合,可排序的,但是唯一。 Sortedset和set的不同之处,是会给set中的元素添加一个 分数,然后通过这个分数进行排序。
增加元素:ZADD key score member [score member ...]
向有序集合中加入一个元素和该元素的分数(score),如果该元素已经存在则会用新的分数替换原有的分数。
添加带分数(可用学生成绩,销售数量等来做分数,方便计算排序):
获得排名在某个范围的元素列表,并按照元素分数降序返回
语法:ZREVRANGE key start stop [WITHSCORES]
获取元素的分数 :ZSCORE key member
删除元素ZREM key member [member ...]
获得元素的分数的可以在命令尾部加上WITHSCORES参数
给某一个属性加分数或减分,减分时使用负数:
5.7 HyoperLogLog命令
5.8 其他命令
(1) keys返回满足给定pattern 的所有key
(2) exists确认一个key 是否存在,存在返回1
(3) del删除一个key
(4) rename重命名key:rename oldkey newkey
(5) type返回值的类型: type key
(6) EXPIRE key seconds
设置key的生存时间(单位:秒)key在多少秒后会自动删除
TTL key 查看key剩余的生存时间
PERSIST key 清除生存时间
(7) 获取服务器信息和统计:info
(8) 删除当前选择数据库中的所有key:flushdb
(9) 删除所有数据库中的所有key:flushall
5.9 Redis的多数据库
一个redis实例key包括多个数据库,客户端可以指定连接某个redis实例的哪个数据库,就好比一个mysql中创建多 个数据库,客户端连接时指定连接哪个数据库。
一个redis实例最多可提供16个数据库,下标从0-15,客户端默认连接第0号数据库,也可以通过select选择连接哪 个数据库,如下连接1号库:select 1
将key的数据移动到1号数据库:
move key 数据库编号
6.Redis的事务管理
Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证:
事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客 户端发送来的命令请求所打断。
事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。
一个事务从开始到执行会经历以下三个阶段: 开始事务。 命令入队。 执行事务。
实例 以下是一个事务的例子, 它先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事 务, 一并执行事务中的所有命令:
7.Redis发布订阅模式
Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
在我们实例中我们创建了订阅频道名为 redisMessage:
现在,我们先重新开启个 redis 客户端,然后在同一个频道 redisMessage 发布两次消息,订阅者就能接收到消 息。
订阅者的客户端会显示如下消息:
8.Jedis连接Redis
方案一 单实例链接:
第一步:创建项目,导入依赖
第二步:链接服务器
方案二:连接池:
public class Demo2 {
public static void main(String[] args) {
//1.创建连接池配置的工具类对象
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(10);//jedis连接的空闲数
jedisPoolConfig.setMaxTotal(20);//总的连接数
JedisPool jedisPool = null;
Jedis jedis = null;
try {
//创建连接池对象
jedisPool = new JedisPool(jedisPoolConfig,"192.168.138.128",6379);
//获得jedis资源
jedis = jedisPool.getResource();
jedis.set("stu1","student1");
String stu1 = jedis.get("stu1");
System.out.println(stu1);
} catch (Exception exception) {
exception.printStackTrace();
} finally {
//5.关闭资源
if (jedis!=null){
jedis.close();
}
if (jedisPool!=null){
jedisPool.close();
}
}
}
}
服务端存储确认:
9.Redis持久化方式
9.1 什么是Redis持久化
由于redis的值放在内存中,为防止突然断电等特殊情况的发生,需要对数据进行持久化备份。即将内存数据保存 到硬盘。
9.2 Redis 持久化存储方式
9.2.1 RDB持久化
RDB 是以二进制文件,是在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化 的文件,达到数据恢复。
优点:使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能
缺点:RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失。所以这种方式更适合 数据要求不严谨的时候
9.2.2 AOF持久化
将“操作 + 数据”以格式化指令的方式追加到操作日志文件的尾部
“日志文件”保存了历史所有的操作过程;当 server 需要数据 恢复时,可以直接 replay 此日志文件,即可还原所有的操作过程。AOF 相对可靠,AOF 文件内容是字符串,非常 容易阅读和解析
优点:可以保持更高的数据完整性,如果设置追加 file 的时间是 1s,如果 redis 发生故障,最多会丢失 1s 的数 据;且如果日志写入不完整支持 redis-check-aof 来进行日志修复;AOF 文件没被 rewrite 之前(文件过大时会对 命令进行合并重写),可以删除其中的某些命令(比如误操作的 flushall)。
缺点:AOF 文件比 RDB 文件大,且恢复速度慢。
其实,我们可以选择的太少,everysec 是最佳的选择。如果你非常在意每个数据都极其可靠,建议你选择一款“关 系性数据库”。
10.Redis主从复制
主从搭建步骤:
主机:不用配置。仅仅只需要配置从机,从机slave配置:(这里是伪集群)
第一步:复制出一个从机,注意使用root用户
cp redis/ redis1 -r
第二步:修改从机的redis.conf
replicaof // replicaof 主机ip 主机端口号
第三步:修改从机的port地址为6380
第四步:清除从机中的持久化文件
注意:
Ø 主机一旦发生增删改操作,那么从机会自动将数据同步到从机中
Ø 从机不能执行写操作,只能读
复制的过程原理
当从库和主库建立MS(master slaver)关系后,会向主数据库发送SYNC命令;
主库接收到SYNC命令后会开始在后台保存快照(RDB持久化过程),并将期间接收到的写命令缓存起来;
快照完成后,主Redis会将快照文件和所有缓存的写命令发送给从Redis;
从Redis接收到后,会载入快照文件并且执行收到的缓存命令;
主Redis每当接收到写命令时就会将命令发送从Redis,保证数据的一致;【内部完成,所以不支持客户端在从 机人为写数据。】
复制架构中出现宕机情况?
从Redis宕机:重启就好
主Redis宕机:从数据库(从机)中执行SLAVEOF NO ONE命令,断开主从关系并且提升为主库继续服务[把一个从做为 主机,这个时候新主机[之前的从机]就具备写入的能力];主服务器修好后,重新启动后,执行SLAVEOF命令,将其 设置为从库[老主机设置为从机]。[手动执行,过程复杂,容易出错。]是否有更好的方案?哨兵模式
11.Redis哨兵模式
哨兵模式:给集群分配一个站岗的。
哨兵的作用就是对Redis系统的运行情况监控,它是一个独立进程,它的功能:
1. 监控主数据库和从数据库是否运行正常;
2. 主数据出现故障后自动将从数据库转化为主数据库;
环境准备:一主两从,启动任一从机时,启动哨兵模式
11.1. 第一步:配置哨兵:
哨兵主要是用来监听主服务器的,所以一般把哨兵部署在从服务器上监听。
11.2. 第二步:启动哨兵:
先启动主服务,后启动从服务
把日志写入指定的文件
./redis-sentinel ./sentinel.conf >sent.log &
启动哨兵的时候,修改了哨兵的配置文件。如果需要再次启动哨兵,需要删除myid唯一标示。
11.3. 第三步:主机宕机
哨兵控制台:从库自动提升为主库。
同时也会自动修改redis.conf的主从配置文件。指向了新主机。再次启动原有的主机,原有的主机会变为从机。
总结:
主从集群:主机有写入权限。从机没有,只有可读。
意外宕机方案:
手动恢复:人为重启服务器,主机宕,把从机设置为主机。
自动恢复:使用哨兵监控。自动切换主从。
12.Redis集群方案
12.1 redis-cluster架构图
架构细节:
(1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.
(2)节点的fail是通过集群中超过半数的节点检测有效时整个集群才生效.
(3)客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
(4)redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护nodeslotvalue
Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽, redis 会根据节点数量大致均等的将哈希槽映射到不同的节点
12.2 redis-cluster投票:容错
心跳机制:
(1)集群中所有master参与投票,如果半数以上master节点与其中一个master节点通信超过(cluster-node-timeout), 认为该master节点挂掉
(2):什么时候整个集群不可用(cluster_state:fail)?
Ø 如果集群任意master挂掉,且当前master没有slave,则集群进入fail状态。也可以理解成集群的[0-16383]slot映 射不完全时进入fail状态。
Ø 如果集群超过半数以上master挂掉,无论是否有slave,集群进入fail状态。