1 Redis介绍
1.1 什么是NoSql数据库
为了解决高并发、高可用、高可扩展,大数据存储等一系列问题而产生的数据库解决方案,就是NoSql。
NoSql,叫非关系型数据库,它的全名Not only sql。它不能替代关系型数据库,只能作为关系型数据库的一个良好补充。
1.2 NoSql的分类
- 键值(Key-Value)存储数据库
- 相关产品: Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB
- 典型应用: 内容缓存,主要用于处理大量数据的高访问负载。
- 数据模型: 一系列键值对
- 优势: 快速查询
- 劣势: 存储的数据缺少结构化
- 列存储数据库
- 相关产品:Cassandra, HBase, Riak
- 典型应用:分布式的文件系统
- 数据模型:以列簇式存储,将同一列数据存在一起
- 优势:查找速度快,可扩展性强,更容易进行分布式扩展
- 劣势:功能相对局限
- 文档型数据库
- 相关产品:CouchDB、MongoDB
- 典型应用:Web应用(与Key-Value类似,Value是结构化的)
- 数据模型: 一系列键值对
- 优势:数据结构要求不严格
- 劣势: 查询性能不高,而且缺乏统一的查询语法
- 图形(Graph)数据库
- 相关数据库:Neo4J、InfoGrid、Infinite Graph
- 典型应用:社交网络
- 数据模型:图结构
- 优势:利用图结构相关算法。
- 劣势:需要对整个图做计算才能得出结果,不容易做分布式的集群方案。
1.3 什么是redis
Redis是使用c语言开发的一个高性能键值数据库。Redis可以通过一些键值类型来存储数据。
Redis有五种键值类型:
- String字符类型
- map散列类型
- list列表类型
- set集合类型
- sortedset有序集合类型
2 Redis的安装
我是在VMwarm虚拟机中的CentOS7系统中安装的3.2.11版本.首先搞一个安装包,附上官网地址
2.1 Redis下载地址
2.2 Redis安装
- 首先你要有一个VMware虚拟机,然后将Redis的安装包copy进去
- 将安装包放进/opt中,解压缩.
- 因为Redis是C语言写的,所以你需要一个C语言的编译环境,我装的CentOS7中自带了C语言的环境,但是没事,运行一遍当更新了.命令行中输入 yum install gcc-c++
- 编译Redis,解压后在/opt中有一个Redis的文件夹,进入此文件夹,命令行输入 make 进行编译
- 安装redis.命令行输入 make install PREFIX=/usr/local/redis(指明安装到哪儿 默认安装在当前路径下)
2.3 Redis启动
进入Redis文件所安装的文件夹中/usr/local/redis
2.3.1 前端启动
前端启动的命令:./redis-server

- 强制关闭:Ctrl+c
- 正常关闭:[root@qf bin]# ./redis-cli shutdown
2.3.2 后端启动
因为Redis在实际使用中不会只是一个Redis单独工作,启动和关闭方式中的ip地址和端口号可以在配置文件中自行修改,下面会有修改方式.
启动方式
- 需要将redis解压之后的源码包中的redis.conf文件拷贝到bin目录下.直接复制粘贴啦
- 修改redis.conf文件,将daemonize改为yes(vi ./redis.conf进去,/daemonize搜索).
- 使用命令后端启动redis.命令行 ./redis-server redis.conf(以配置文件启动)
- 查看是否启动成功.命令行 ps -aux | grep redis (直接查看redis的进程)

- 强制关闭:kill -9 5071
- 正常关闭:./redis-cli -h ip地址 -p 端口号(默认端口号是6379) shutdown
在项目中,建议使用正常关闭。 因为redis作为缓存来使用的话,将数据存储到内存中,如果使用正常关闭,则会将内存数据持久化到本地之后,再关闭。如果是强制关闭,则不会进行持久化操作,可能会造成部分数据的丢失。
3 Redis客户端
3.1 Redis自带客户端
启动客户端命令:[root@qf bin]# ./redis-cli -h ip地址 -p 端口号
退出:127.0.0.1:6379> quit
4 Redis配置文件修改
4.1 配置文件修改:
进入usr/local/redis/bin中,命令行输入vi ./redis.conf进入.找到bind和port直接修改就可以.bind是ip地址,如果使用默认的127.0.0.1,远程连接是连接不上的.port是端口号,起一个没被占用的就行.
5 Redis的16个默认数据库
Redis既然是存储在内存中缓存的,那么为什么还需要数据库呢?
如果哪天redis宕机了(挂了),那么没有数据库的情况下内村中的数据就会消失,有数据库是为了redis宕机的时候防止数据消键被失,将数据存到数据库中,如果redis发生宕机,那么重新启动后还会将数据库中的数据恢复到内存中,不至于数据消失.
5.1 Redis的两种持久数据的方式
- 默认持久化方式RDB
默认持久化方式是rdb方式,(RDB也指关系数据库(RelationalDatabase,RDB),关系数据库就是基于关系型的数据库,是利用数据库进行数据组织的一种方式,是现代的数据库管理系统中应用最为普遍的一种,也是最有效的数据组织形式之一。)但是必须满足持久化条件,在Redis的配置文件中可以看到rdb的三个默认条件,只需要满足任意一个条件就会持久化.
- save 900 1 在15分钟内至少一个键被改变
- save 300 10 在五分钟内至少10个键被改变
- save 60 10000 在一分钟内至少10000个键被改变
默认存储文件是dbfilename dump.rdb
- AOF持久化方式
默认只使用rdb,但是有风险,又提供了一种aof方式(AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。每隔一秒持久化一次,就算丢失也是少量).
在配置文件中将appendonly no 改为yes.
两个同时开启时,宕机后根据哪一个进行恢复?:如果同时使用了AOF和RDB,使用AOF的进行恢复!
6 Redis的存储,复制,删除命令
这个就太多了,写不过来,各位自己动动手整理一下,都是比较简单的命令
7 Redis的主从复制
7.1 什么是主从复制
持久化保证了即使redis服务重启也不会丢失数据,因为redis服务重启后会将硬盘上持久化的数据恢复到内存中,但是当redis服务器的硬盘损坏了可能会导致数据丢失,如果通过redis的主从复制机制就可以避免这种单点故障,如下图:

- 主redis中的数据有两个副本(replication)即从redis1和从redis2,即使一台redis服务器宕机其它两台redis服务也可以继续提供服务。
- 主redis中的数据和从redis上的数据保持实时同步,当主redis写入数据时通过主从复制机制会复制到两个从redis服务上。
- 只有一个主redis,可以有多个从redis。
- 主从复制不会阻塞master,在同步数据时,master 可以继续处理client 请求
- 一个redis可以即是主又是从,如下图:

7.2 主从复制的设置
- 主机:无配置
- 从机:
- 第一步:复制出一个Redis文件夹(从机)
- 第二步:修改从机的redis.conf(配置文件),找到slaveof masterip masterport,在下面配置slaveof 10.0.111.129(主机ip地址) 6379(主机端口号)
- 第三步:修改从机的port端口号,我设置的是6380.
- 第四步:清除从机中的持久化文件appendonly.aof和dump.rdb.很重要,因为在创建主从复制的时候从机是不能有任何数据的,否者创建失败.
- 第五步:启动主机
- 第六步:启动从机
- 第七步 测试 主机客户端:set test 11 从机客户端:get test
注意:从机不能执行写操作,否则会报错:(error) READONLY You can't write against a read only slave.
8 Redis集群
8.1 Redis-cluster架构图

- 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.
- 节点的fail是通过集群中超过半数的节点检测失效时才生效.
- 客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可.
- redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->value.
Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点
8.2 Redis-cluster投票:容错

- 集群中所有master参与投票,如果半数以上master节点与其中一个master节点通信超过(cluster-node-timeout),认为该master节点挂掉.
- 什么时候整个集群不可用(cluster_state:fail)?
- 如果集群任意master挂掉,且当前master没有slave,则集群进入fail状态。也可以理解成集群的[0-16383]slot映射不完全时进入fail状态。
- 如果集群超过半数以上master挂掉,无论是否有slave,集群进入fail状态。
8.3 搭建集群
经济限制,没那么多电脑来搭建集群,只能拿自己的老年机来搭建一个伪集群来搞一搞.
- 安装ruby(集群管理工具(redis-trib.rb)是使用ruby脚本语言编写的。)
- yum install ruby
- yum install rubygems
- 搞一个redis接口过来,上网下一个,我用的是redis-3.3.5.gem
- 运行 gem install redis-3.0.0.gem
- 在/usr/local/redis中创建一个文件夹,名字任意,我的叫cluster,在文件夹中创建6个redis文件夹,以端口号命名.
- 将/opt/redis-3.2.11文件夹中的src粘贴到六个文件夹中,再讲redis.conf配置文件copy过来,修改配置文件中的cluster-enabled yes(默认是注释上的,主要删掉注释符号即可).修改六个配置文件的端口号,体力活,撸吧
- 开启六个reids服务,也是体力活,然后查看服务是否都开启了.


9 java代码进行连接redis
9.1 java代码连接单个redis
非常重要的一点,关闭linux的虚拟机!关闭linux的虚拟机!关闭linux的虚拟机!重要的事情说三遍!
java
package com.itqf.test;
import java.util.HashSet;
import java.util.Set;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;
public class TestRedis {
public static void main(String[] args) {
//访问单机版的redis
Jedis jedis =new Jedis("10.0.117.198", 6379);
jedis.set("cry", "wawaku");
String value = jedis.get("cry");
System.out.println(value);
jedis.close();
//使用Jedis池
JedisPool pool=new JedisPool("10.0.117.198", 6379);
Jedis jedis2 = pool.getResource();
String v =jedis2.get("cry");
System.out.println(v);
jedis2.close();
//访问集群 首先你得开启集群
Set<HostAndPort> nodes = new HashSet<>();
nodes.add(new HostAndPort("10.0.117.198", 6381));
nodes.add(new HostAndPort("10.0.117.198", 6382));
nodes.add(new HostAndPort("10.0.117.198", 6383));
nodes.add(new HostAndPort("10.0.117.198", 6384));
nodes.add(new HostAndPort("10.0.117.198", 6385));
nodes.add(new HostAndPort("10.0.117.198", 6386));
JedisCluster cluster = new JedisCluster(nodes);
cluster.set("test","1111");
String str = cluster.get("test");
System.out.println(str);
cluster.close();
}
}