Redis是什么?Redis有哪些数据类型?Redis怎么集群?

Redis


本文所需资源文件

一、Redis概念

1.NoSql

1.1 什么是NoSql

NoSQL,泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在处理web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,出现了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。

1.2 NoSql分类

在这里插入图片描述

2 Redis

2.1 什么是Redis

Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。它支持字符串、哈希表、列表、集合、有序集合,位图,hyperloglogs等数据类型。内置复制、Lua脚本、LRU收回、事务以及不同级别磁盘持久化功能,同时通过Redis Sentinel提供高可用,通过Redis Cluster提供自动分区。

2.2 Redis的优点
1)响应快速

Redis 响应非常快,每秒可以执行大约 110 000 个写入操作,或者 81 000 个读操作,其速度远超数据库。如果存入一些常用的数据,就能有效提高系统的性能。

2)支持 6 种数据类型

它们是字符串、哈希结构、列表、集合、可排序集合和基数。比如对于字符串可以存入一些 Java 基础数据类型,哈希可以存储对象,列表可以存储 List 对象等。这使得在应用中很容易根据自己的需要选择存储的数据类型,方便开发。

对于 Redis 而言,虽然只有 6 种数据类型,但是有两大好处:一方面可以满足存储各种数据结构体的需要;另外一方面数据类型少,使得规则就少,需要的判断和逻辑就少,这样读/写的速度就更快。

3)操作都是原子的

所有 Redis 的操作都是原子的,从而确保当两个客户同时访问 Redis 服务器时,得到的是更新后的值(最新值)。在需要高并发的场合可以考虑使用 Redis 的事务,处理一些需要锁的业务。

4)MultiUtility 工具

Redis 可以在如缓存、消息传递队列中使用(Redis 支持“发布+订阅”的消息模式),在应用程序如 Web 应用程序会话、网站页面点击数等任何短暂的数据中使用。

2.3Redis的使用场景

正是因为 Redis 具备这些优点,使得它成为了目前主流的 NoSQL 技术,在 Java 互联网中得到了广泛使用。一方面,使用 NoSQL 从数据库中读取数据进行缓存,就可以从内存中读取数据了,而不像数据库一样读磁盘。现实是读操作远比写操作要多得多,所以缓存很多常用的数据,提高其命中率有助于整体性能的提高,并且能减缓数据库的压力,对互联网系统架构是十分有利的。另一方面,它也能满足互联网高并发需要高速处理数据的场合,比如抢红包、商品秒杀等场景,这些场合需要高速处理,并保证并发数据安全和一致性。

二、Redis使用

1.Redis的安装

1.1.下载Redis

Redis中文官网
Redis英文官网

1.2.安装Redis

Windows:下载后,直接解压即可使用

linux:
在这里插入图片描述

1.3.Redis目录介绍

在这里插入图片描述

1.4.启动Redis-server

启动redis-server.exe

1.5.启动Redis-client

启动redis-cli.exe

2.Redis的入门

在这里插入图片描述

2.1.key的操作
  • keys * :查看所有key
  • del key :删除某个key
  • expire key : 设置key的过期时间
  • ttl key:查看key的过期时间
  • flushall :删除所有库的数据
  • flushdb:删除当前数据库
  • select 1 :选择第索引为1的数据库,默认有16个 ,索引 0 - 15
2.2.String的操作
  • set key value :存储一个键值对
  • get key :获取某个值
  • mset key value key value :设置多个键值对
  • mget key key :获取多个key的值
  • incr key :key的值加 1
  • decr key :key的减去 1
  • incrBy key number:key的值自增多少
  • decrBy key number: key的值自减去多少
2.3.List的操作
  • lpush key value value value :从左边存
  • rpush key value value value :从右边存
  • lrange key start end :取范围内的元素 0 -1 查询所有
  • lpop key : 从左边移出一个并返回
  • rpop key :从右边移出一个并返回
  • lrem key count value :删除 ,key中的value,count > 0从左边删除count个相同元素,count< 0 从右边删除count个相同元素 ,count == 0删除所有
  • lindex key index :返回列表 key 中,下标为 index 的元素
  • ltrim key start stop :对一个列表进行修剪,把范围外的删除,保留范围内的元素
2.4.Set的操作
  • sadd key member member member:将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略
  • srem key member :移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略
  • smembers key :返回集合 key 中的所有成员。
2.5.ZSet的操作
  • zadd key score member score member : 添加 score是member的分数
  • zcard key: 成员数量
  • zcount key start end :范围内的元素个数
  • zrange:分数排序从小到大
  • zrevrange:分数从大到小排序
2.6.Hash的操作
  • hset 大key 小key value
  • hget 大key 小key
  • hmset 大key 小key value 小key value
  • hmget 大key 小key 小key
  • hkeys :获取所有key
  • hvals:获取所有值
  • hgetall :获取所有的key和value

如何存储一个对象:

方式一(String): set user:1 {“id”:1,username:“zs”}

方式二(hash) : hmset user:1 id 1 username zs

3.Redis设置密码

3.1.设置密码

修改配置文件:redis.windows.conf 443行
requirepass + “密码”
使用cmd执行 redis-server.exe redis.windows.conf命令重载配置文件

3.2.登录

auth命令

4.Redis中的事务

在这里插入图片描述

4.1.事务概念

事务:一般是指要做的或所做的事情。指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transaction和end transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。

4.2.操作事务

CMD操作:

redis 127.0.0.1:6379> MULTI
OK

redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days"
QUEUED

redis 127.0.0.1:6379> GET book-name
QUEUED

redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series"
QUEUED

redis 127.0.0.1:6379> SMEMBERS tag
QUEUED

redis 127.0.0.1:6379> EXEC
1) OK
2) "Mastering C++ in 21 days"
3) (integer) 3
4) 1) "Mastering Series"
   2) "C++"
   3) "Programming"

Redis事务

4.3.Redis事务原理

Redis事务剖析

5.发布/订阅

Redis发布/订阅

在这里插入图片描述

5.1.发布订阅概念

命令:
SUBSCRIBE channel

5.2.操作发布订阅

命令:
PUBLISH channel message

三、JAVA操作数据库

1. 选择java客户端

原来mysql需要使用jdbc,现在需要redis的一个java客户端jedis。
jedis是客户端,而reids是服务器。使用jedis这个java客户端操作redis数据库。

在这里插入图片描述
导包:
Redis连接池:commons-pool2-2.2.jar
Redis核心包:jedis-2.5.2.jar
在这里插入图片描述#### 2. Jedis简单操作

2.1. 简单配置

使用jedis 客户端,完成jedis简单操作

@Test
public void test()throws Exception{
    //创建连接
    String host ="127.0.0.1";
    int port = 6379;
    int timeout = 1000;//超时时间,1秒超时
    Jedis jedis = new Jedis(host,port,timeout);
    jedis.auth("admin");
    //执行操作
    jedis.set("yhptest","yhptest dbl!");
    System.out.println(jedis.get("yhptest"));
    //关闭连接
    jedis.close();
}

2.2. 连接池配置

池化技术
通过jedis连接池,简单操作redis数据库

@Test
public void test()throws Exception{
    //1 创建jedispool配置对象
    JedisPoolConfig config = new JedisPoolConfig();
    //2 做配置-四个
    config.setMaxIdle(2);
    config.setMaxTotal(10);
    config.setMaxWaitMillis(1*1000); //创建连接超时
    config.setTestOnBorrow(true);//获取连接是测试连接是否畅通
    //3 创建jedispool
    //1*1000 获取连接超时时间
    JedisPool pool = new JedisPool(config,
            "127.0.0.1",6379,1*1000,"admin");
    //4 通过jedispool获取连接
    Jedis jedis = pool.getResource();
    //5 执行操作
    jedis.set("jedispooltest","dbldblddzt.....");
    System.out.println(jedis.get("jedispooltest"));
    // 6 释放连接
    jedis.close(); //底层做了兼容,如果是连接池操作就是释放,如果是连接操作就是关闭
    // 7 摧毁连接池-如果是真正项目中它应该是一个受spring管理的单例
    pool.destroy();
}

2.3 JedisPool工具类抽取
public class RedisUtil {
	// 创建一个空的连接池对象
    private static JedisPool pool = null;

    static {
        //1 创建jedispool配置对象
        JedisPoolConfig config = new JedisPoolConfig();
        //2 做配置-四个
        // 最大空闲数
        config.setMaxIdle(2);
        // 最大连接数
        config.setMaxTotal(10);
        // 创建连接超时
        config.setMaxWaitMillis(1*1000);
        // 获取连接是测试连接是否畅通
        config.setTestOnBorrow(true);
        //3 创建jedispool
        
        /**
         * new JedisPool(GenericObjectPoolConfig poolConfig, String host, int port, int timeout, String password)
         * poolConfig::连接池配置
         * host:连接地址
         * port:端口
         * timeout:超时时间
         * password:密码
         */
         
        pool = new JedisPool(config,"127.0.0.1",6379,1*1000,"123456");
    }

    public static Jedis getJedis(){
        return pool.getResource();
    }
}

2.4. Jedis数据结构操作

使用jedis来操作redis的key和value,而value有很多种类型,和命令操作一样。

/**
     * Redis key的操作
     * @throws Exception
     */
    @Test
    public void testKey() throws Exception{
        Jedis jedis = RedisUtil.getJedis();
        // 查看所有key
        System.out.println(jedis.keys("*"));
        // 设置key过期时间
        jedis.expire("name",2000);
        Thread.sleep(2000);
        // 查看key过期时间
        System.out.println(jedis.ttl("name"));
        // 删除一个key
        jedis.del("name");
        System.out.println(jedis.keys("*"));
        // 删除所有key
        jedis.flushAll();
        System.out.println(jedis.keys("*"));
    }

    /**
     * Redis String的操作
     * @throws Exception
     */
    @Test
    public void testString() throws Exception{
        Jedis jedis = RedisUtil.getJedis();
        // 存储一个键值对
        jedis.set("name","赵四");
        // 获取key为name的值
        System.out.println(jedis.get("name"));
        // 设置多个键值对
        jedis.mset("age","11","sex","0");
        // 获取多个key的值
        System.out.println(jedis.mget("name", "age", "sex"));
        //key:age的值加 1
        jedis.incr("age");
        System.out.println(jedis.get("age"));
        //key:age的值减 1
        jedis.decr("age");
        System.out.println(jedis.get("age"));
        //key:age的值加 10
        jedis.incrBy("age",10);
        System.out.println(jedis.get("age"));
        //key:age的值减 10
        jedis.decrBy("age",10);
        System.out.println(jedis.get("age"));
        jedis.flushAll();
    }

    /**
     * List的操作
     * @throws Exception
     */
    @Test
    public void testList() throws Exception{
        Jedis jedis = RedisUtil.getJedis();
        // 从左边存
        jedis.lpush("names","岳云鹏","孙中山","刘德华","刘德华","刘德华","刘德华","火绒");
        // 取范围内的元素 0 -1 查询所有
        System.out.println(jedis.lrange("names", 0, -1));
        // 从右边存
        jedis.rpush("names","赵云","刘备","关羽","关羽","关羽","关羽","杨彧");
        // 取范围内的元素 0 -1 查询所有
        System.out.println(jedis.lrange("names", 0, -1));
        // 从左边移出一个并返回
        System.out.println(jedis.lpop("names"));
        // 从右边移出一个并返回
        System.out.println(jedis.rpop("names"));
        System.out.println(jedis.lrange("names", 0, -1));
        // 删除 ,key中的value,count > 0从左边删除count个元素,count< 0 从右边删除count个 ,count == 0删除所有
        jedis.lrem("names",2,"刘德华");
        System.out.println(jedis.lrange("names", 0, -1));
        jedis.lrem("names",-2,"关羽");
        System.out.println(jedis.lrange("names", 0, -1));
        // 返回列表 key 中,下标为 index 的元素
        System.out.println(jedis.lindex("names", 3));
        // 对一个列表进行修剪,把范围外的删除,保留范围内的元素
        jedis.ltrim("names",1,3);
        System.out.println(jedis.lrange("names", 0, -1));
        jedis.flushAll();
    }

    /**
     *  Set的操作
     */
    @Test
    public void testSet() throws Exception{
        Jedis jedis = RedisUtil.getJedis();
        // 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略
        jedis.sadd("name","哪吒","哪吒","小猪熊","小龙女","李靖","山鬼","姬发","龙须虎","石矶","妲己","土行孙","申公豹","雷震子","李靖","");
        // 返回集合 key 中的所有成员。
        jedis.smembers("name").forEach(e->System.out.print(e + ","));
        System.out.println();
        // 移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略
        jedis.srem("name","石矶","申公豹");
        // 返回集合 key 中的所有成员。
        jedis.smembers("name").forEach(e->System.out.print(e + ","));
        jedis.flushAll();
    }

    /**
     * ZSet的操作
     * @throws Exception
     */
    @Test
    public void testzset() throws Exception{
        Jedis jedis = RedisUtil.getJedis();
        // 添加  score是member的分数
        jedis.zadd("grade",90,"喜羊羊");
        jedis.zadd("grade",90,"喜羊羊");
        jedis.zadd("grade",90,"喜羊羊");
        // 成员数量
        System.out.println(jedis.zcard("grade"));
        jedis.flushAll();
        String key = "grade";
        Map student = new HashMap<>(10);
        student.put("喜羊羊",90.0);
        student.put("美羊羊",80.0);
        student.put("暖羊羊",70.0);
        student.put("沸羊羊",60.0);
        student.put("懒羊羊",50.0);
        // 添加  map
        jedis.zadd(key,student);
        // 成员数量
        System.out.println(jedis.zcard("grade"));
        // 分数范围内的元素个数
        System.out.println(jedis.zcount("grade", 50, 70));
        // 分数排序从小到大
        jedis.zrange("grade",0,-1).forEach(e-> System.out.print(e + ","));
        System.out.println();
        //分数从大到小排序
        jedis.zrevrange("grade",0,-1).forEach(e-> System.out.print(e + ","));
        jedis.flushAll();
    }

    /**
     * Hash的操作
     * @throws Exception
     */
    @Test
    public void testHash() throws Exception{
        Jedis jedis = RedisUtil.getJedis();
        // 存map或json: hset  大key(user)  小key(name)  value(熊大)
        jedis.hset("user","name","熊大");
        // 获取值hget 大key(user) 小key(name0
        System.out.println(jedis.hget("user", "name"));

        Map map = new HashMap(10);
        map.put("age", "28");
        map.put("sex", "1");
        // 批量map或json:hmset 大key  Map
        jedis.hmset("user",map);
        // 批量获取map或json,hmget 大key(user) 小key(name) 小key(age) 小key(sex)
        jedis.hmget("user","name", "age", "sex").forEach(e-> System.out.print(e + ","));
        System.out.println();
        // 获取所有key
        System.out.println(jedis.hkeys("user"));
        // 获取所有值
        System.out.println(jedis.hvals("user"));
        // 获取所有的key和value
        System.out.println(jedis.hgetAll("user"));
        jedis.flushAll();
    }

四.Redis的持久化配置

1.配置文件介绍

1.1.配置项介绍
  • bind : 指定的ip才能访问
  • port : 默认端口
  • timeout : 连接超时
  • loglevel : 日志的级别
  • logfile : 日志文件输出路径
  • databases : 数据库数量
  • save 900 1 : RDB持久方式,900 秒有一个数据修改进行持久化
  • appendonely : AOF持久方式

2.持久化配置

2.1.RDB
① 概述

默认redis是会以快照的形式将数据持久化到磁盘的(一个二进制文件,dump.rdb,这个文件名字可以指定),在配置文件中的格式是:save N M表示在N秒之内,redis至少发生M次修改则redis抓快照到磁盘。当然我们也可以手动执行save或者bgsave(异步)做快照。

② 实现机制

当redis需要做持久化时,redis会fork一个子进程;子进程将数据写到磁盘上一个临时RDB文件中;当子进程完成写临时文件后,将原来的RDB替换掉,这样的好处就是可以copy-on-write

③ 相关配置

redis.conf配置文件:

  1. 持久化策略:
#  save ""

save 900 1

save 300 10

save 60 10000
  1. 文件名称:
# The filename where to dump the DB

dbfilename dump.rdb
  1. 文件存放目录:
# Note that you must specify a directoryhere, not a file name.

dir ./
2.2.AOF

AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集,默认关闭该模式。
如何开启xmlaof模式:

appendonly yes         //yes 开启,no 关闭
# appendfsync always //每次有新命令时就执行一次fsync 
#这里我们启用 everysec
appendfsync everysec //每秒 fsync 一次
# appendfsync no      //从不fsync(交给操作系统来处理,可能很久才执行一次fsync)

其它的参数请大家看redis.conf配置文件详解

五.Redis的淘汰策略

1.为什么要淘汰数据

淘汰一些数据,达到redis数据都是有效的。选择合适的淘汰策略进行淘汰。

2.怎么淘汰

淘汰一些数据,达到redis数据都是有效的。选择合适的淘汰策略进行淘汰。
volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据
redis 确定驱逐某个键值对后,会删除这个数据并,并将这个数据变更消息发布到本地(AOF 持久化)和从机(主从连接)。

六.集群理解

1.集群概念

1.1.为什么要集群
  • 防止单点故障 : 不做集群,那么服务器挂了,整个应用就挂了
  • 实现高可用(作业能力) :一个服务器的能力有限,多个服务器可以提升作业能力,和提升可用性
1.2.集群和分布式
  • 什么 是集群

多个服务器做相同的事情,他们的所有代码,处理的业务都是一样的 , 每个服务器都是一个完整的应用

  • 什么是分布式

多个服务器做不同的事情,每个服务的代码,处理的业务都是不一样的,所有的服务器组成一个完整的应用

  • 生活举例

    3个厨师:

    集群 - 每个厨师都要负责洗菜,切菜,炒菜

    分布式 - 一个厨师只负责洗菜,一个厨师只负责切菜,一个厨师只负责炒菜
    图片.png

图片.png

1.3.集群的特性

集群应该具有如下特性:

  • 可扩展性 : 灵活的动态增加/减少服务器
  • 高可用性 :(防止单点故障)一个服务器挂了,还有另外的服务器顶着。一个请求过来,总会有相应结果
1.4.集群的能力

集群应该具备如下能力:

  • 负载均衡

    把请求根据某种算法分发(路由)到集群的应用

  • 错误恢复

    集群下的某个应用挂了需要找到能用的服务继续处理请求 , 并且挂掉的服务可以根据没挂服务做(数据)恢复

  • 主备切换 - Redis

    对于应用的集群,某个应用挂掉了,集群中需要有其他的应用顶上以处理请求。
    图片.png

1.5.分布式和集群区别

​ 集群是多个节点处理相同的任务,分布式是多个节点处理不同的任务

2.Redis集群概念

2.1.Redis为什么做集群
  • 防止单点故障
  • 处理高并发/高可用
  • 处理大量数据
2.2.Redis主从复制
  • 什么是主从复制(读写分离)

    主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到从节点。默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。

    写请求到主Redis,读请求到从Redis ,读/写的路由需要负载均衡器(主Twemproxy/从Twemproxy) ,而主从Redis的负载均衡器需要做主备切换(keeplived)

    图例:
    图片.png

  • 主从复制的作用

    数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。

    故障恢复:当主节点出现问题时可以由从节点提供服务实现快速的故障恢复;实际上是一种服务的冗余

    负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。

    读写分离:可以用于实现读写分离,主库写、从库读,读写分离不仅可以提高服务器的负载能力,同时可根据需求的变化,改变从库的数量。

    高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。

  • 主从的缺点

    不具备自动容错和恢复功能 :主从宕机会影响前端的部分请求失败,需要重启机器或者手动切换前端IP才能恢复

    主机宕机数据丢失:宕机前部分有部分数据未同步到从机,切换IP后会引入数据不一致降低系统可用性

    数据大的问题:数据量特别大一个主是存储不了

2.3.Redis哨兵模式
  • 什么是哨兵模式

    当主服务器中断服务后,可以将一个从服务器升级为主服务器,以便继续提供服务,但是这个过程需要人工手动来操作。 为此,Redis 2.8中提供了哨兵工具来实现自动化的系统监控和故障恢复功能。

    图例:
    图片.png

    哨兵模式的优点:拥有主从的所有有点, 可以自动的检查,实现故障恢复功能(从提升为主)。

    哨兵模式的缺点: 还是不能存储大量数据

2.4.Redis-Cluster集群

拥有主从和哨兵的所有有点 ,并解决了数据存储的问题
图片.png

  • 为什么要Redis-Cluster

    redis的哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台redis服务器都存储相同的数据,很浪费内存,所以在redis3.0上加入了cluster模式,实现的redis的分布式存储,也就是说每台redis节点上存储不同的内容

  • 什么是Redis-Cluster

    Redis-Cluster采用无中心结构,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态。每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据

  • 数据分散存储

    Redis 集群没有并使用传统的一致性哈希来分配数据,而是采用另外一种叫做哈希槽 (hash slot)的方式来分配的。redis cluster 默认分配了 16384 个slot,当我们set一个key 时,会用CRC16算法来取模得到所属的slot,然后将这个key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 16384

  • 容错机制-投票

    为了防止主节点数据丢失,可以为每个主节点可以准备特点数目的备节点,主节点挂掉从节点可以升级为主节点(哨兵模式) 。

    容错机制指的是,如果半数以上master节点与故障节点通信超过(cluster-node-timeout),认为该节点故障,自动触发故障转移操作. 故障节点对应的从节点自动升级为主节点 , 如果某个主挂掉,而没有从节点可以使用,那么整个Redis集群进入宕机状态

2.5.总结

a.主从复制

  • 概念:一主多重,主读写,从读,从复制主的数据,解决读的压力
  • 缺点:主挂了集群就挂了,没办法自动的容错(从提升为主) ,没办法存储大量数据

b.哨兵模式

  • 概念: 基于主从实现自动化的容错(从提升为主) ,拥有主从的全部特点
  • 缺点:没办法存储大量数据

c.集群模式

  • 概念:在哨兵的基础上实现多主,每个主可以有多 从
  • 优点:实现了数据的分布式存储(每个主存储数据不一样),同时拥有所有的哨兵,主从的有点

七.Redis集群搭建

1.环境准备

1.1.Redis 3.2

​ 需要 6 台 redis 服务器。搭建伪集群。

​ 需要 6 个 redis 实例。

​ 需要运行在不同的端口 6379-6384

1.2.Ruby语言运行环境

​ 我们需要使用ruby脚本来实现集群搭建

  • Ruby 打包系统RubyGems

    RubyGems简称gems,是一个用于对 Ruby组件进行打包的 Ruby 打包系统

  • Redis的Ruby驱动redis-xxxx.gem

  • 创建Redis集群的工具redis-trib.rb

2.Redis安装

2.1.安装6台Redis

在Window搭建6个伪集群

每个Redis创建启动脚本start.bat,内容如下

title redis-3679
redis-server.exe redis.windows.conf
2.2.Redis配置

修改redis.windows.conf,端口号分别对应:6379、6380、6381、6382、6383、6384。

开启cluster-enabled :cluster-enabled yes

指定集群配置文件: cluster-config-file nodes-6379.conf,cluster-config-file nodes-6379.conf 是为该节点的配置信息,这里使用 nodes-端口.conf命名方法。服务启动后会在目录生成该文件。

指定超时:cluster-node-timeout 15000

开启持久:appendonly yes

2.3.安装Ruby

rubyinstaller-2.6.3-1-x64.exe 傻瓜式安装即可
图片.png

4.安装Ruby驱动

1.解压Ruby驱动(rubygems-3.0.6.zip) , 进入根目录(解压目录),执行

ruby setup.rb

图片.png

图片.png

2.5.执行集群构建脚本

1.启动6个Redis

2.拷贝redis-trib.rb到Redis目录(6379的Redis目录)

3.在6379根目录执行构建脚本:

redis-trib.rb create --replicas 1 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384

4.在出现 Can I set the above configuration? (type ‘yes’ to accept): 请确定并输入 yes 。成功后的结果如下:
图片.png

2.6.测试集群命令

启动客户端:redis-cli –c –h 127.0.0.1 –p 6379 , 可以跟任何节点的端口

查看整个集群:cluster info

查看当前Redis:info replication

查看槽位:cluster nodes

2.7.集群代码测试
@Test
public void testCluster() throws IOException, InterruptedException {
    Set<HostAndPort> nodes = new HashSet<>();
    nodes.add(new HostAndPort("127.0.0.1", 6379));
    nodes.add(new HostAndPort("127.0.0.1", 6380));
    nodes.add(new HostAndPort("127.0.0.1", 6381));
    nodes.add(new HostAndPort("127.0.0.1", 6382));
    nodes.add(new HostAndPort("127.0.0.1", 6383));
    nodes.add(new HostAndPort("127.0.0.1", 6384));
    JedisCluster cluster = new JedisCluster(nodes);
    try {
        String res = cluster.get("name");
        System.out.println(res);
    	//cluster.quit();
    } catch (Exception e) {
    	e.printStackTrace();
    	//cluster.quit();
    }
}

八.总结

一.作业

1.所有命令
2.java代码

二.重点

1.nosql,redis概念
2.Redis特点
3.使用场景
4.各种命令
5.Jedis的使用
6.持久化概念+淘汰策略概念 - 说的清楚,知道怎么配
7.集群和分布式的概念,区别 - 说的清楚
8.Redis集群的三种模式
9.集群的搭建和使用

三.面试题

1)简单说一下你对分布式理解?

2)简单说一下你对集群理解?

3)说一下分布式和集群联系和区别

4)Redis集群方式有哪些?

5)简单说一下Redis-cluster里面槽?

Redis 集群没有并使用传统的一致性哈希来分配数据,而是采用另外一种叫做`哈希槽 (hash slot)`的方式来分配的。redis cluster 默认分配了 16384 个slot,当我们set一个key 时,会用`CRC16`算法来取模得到所属的`slot`,然后将这个key 分到哈希槽区间的节点上,具体算法就是:`CRC16(key) % 16384`。

6)简单说一下Redis-cluster里面选举投票机制

7)怎么通过命令连接redis集群 -c

8)怎么通过jedis连接集群

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值