redis与分布式

这篇具有很好参考价值的文章主要介绍了redis与分布式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

主从复制

概念

主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(Master),后者称为从节点(Slave),数据的复制是单向的,只能由主节点到从节点。Master以写为主,Slave 以读为主(只读模式),当主节点关闭后,从节点依然可以读取数据,但是会报错

redis与分布式,redis,redis,分布式,数据库

优点

  • 实现了读写分离,提高了性能

  • 在写少读多的场景下,我们甚至可以安排很多个从节点,这样就能够大幅度的分担压力,并且就算挂掉一个,其他的也能使用

实验

打开两个redis服务器,修改配置文件redis.conf的端口

redis与分布式,redis,redis,分布式,数据库

一个服务器的端口设定为6001,复制一份,另一个的端口为6002,再分别指定配置文件进行启动

redis-server.exe redis.conf

输入info replication命令来查看当前的主从状态,可以看到默认的角色为:master,也就是说所有的服务器在启动之后都是主节点的状态,在6002的客户端输入slaveof/replicaof 127.0.0.1 6001命令后,就会将6001服务器作为主节点,而当前节点作为6001的从节点,并且角色也会变成:slave,而且从节点信息中已经出现了6002服务器,也就是说现在6001和6002就形成了主从关系(还包含一个偏移量,这个偏移量反应的是从节点的同步情况)

redis与分布式,redis,redis,分布式,数据库

 

主服务器和从服务器都会维护一个复制偏移量,主服务器每次向从服务器中传递 N 个字节的时候,会将自己的复制偏移量加上 N。从服务器中收到主服务器的 N 个字节的数据,就会将自己额复制偏移量加上 N,通过主从服务器的偏移量对比可以很清楚的知道主从服务器的数据是否处于一致,如果不一致就需要进行增量同步了

测试:在主节点新增数据,同步到从节点

redis与分布式,redis,redis,分布式,数据库

 

通过输入replicaof/slaveof no one,即可变回Master角色

新增从节点同步流程

  • 从节点执行replicaof ip port命令后,从节点会保存主节点相关的地址信息。

  • 从节点通过每秒运行的定时任务发现配置了新的主节点后,会尝试与该节点建立网络连接,专门用于接收主节点发送的复制命令。

  • 连接成功后,第一次会将主节点的数据进行全量复制,之后采用增量复制,持续将新来的写命令同步给从节点。

配置文件配置主节点

replicaof 127.0.0.1 6001    #填到从节点的配置文件中

还可以使某节点作为从节点的从节点

replicaof 127.0.0.1 6002    #填到从节点6003的配置文件中

redis与分布式,redis,redis,分布式,数据库

 

从节点分布

redis与分布式,redis,redis,分布式,数据库

 

第二个分布的缺点:整个传播链路一旦中途出现问题,那么就会导致后面的从节点无法及时同步

哨兵模式

这里的哨兵是是专用于Redis的。哨兵会对所有的节点进行监控,如果发现主节点出现问题,那么会立即从从节点选举一个新的主节点出来,这样就不会由于主节点的故障导致整个系统不可写

类似于服务治理模式,比如Nacos和Eureka,所有的服务都会被实时监控,那么只要出现问题,肯定是可以及时发现的,并且能够采取响应的补救措施

redis与分布式,redis,redis,分布式,数据库

 

如何添加哨兵:直接删除配置文件的全部内容并添加如下内容

#第一个和第二个是固定,第三个是为监控对象名称,随意,后面就是主节点的相关信息,包括IP地址和端口
sentinel monitor lbwnb 127.0.0.1 6001 1

选举规则:

  1. 首先会根据优先级进行选择,可以在配置文件中进行配置,添加replica-priority配置项(默认是100),越小表示优先级越高

  2. 如果优先级一样,那就选择偏移量最大的

  3. 要是还选不出来,那就选择pid(启动时随机生成的)最小的

可以修改配置中的端口实现多个哨兵

与Java互动

在哨兵重新选举新的主节点之后,Java中的Redis的客户端怎么感知到呢

<dependencies>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>4.2.1</version>
    </dependency>
</dependencies>
public class Main {
    public static void main(String[] args) {
        //直接使用JedisSentinelPool来获取Master节点
        //需要把三个哨兵的地址都填入
        try (JedisSentinelPool pool = new JedisSentinelPool("lbwnb",
                new HashSet<>(Arrays.asList("127.0.0.1:26741", "127.0.0.1:26740", "127.0.0.1:26739")))) {
            Jedis jedis = pool.getResource();   //直接询问并得到Jedis对象,这就是连接的Master节点
            jedis.set("test", "114514");    //直接写入即可,实际上就是向Master节点写入
​
            Jedis jedis2 = pool.getResource();   //再次获取
            System.out.println(jedis2.get("test"));   //读取操作
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

集群搭建

因为单机的内存容量有限,已经没办法再继续扩展时,但又需要存储更多的内容,这时就可以让N台机器上的Redis来分别存储各个部分的数据(每个Redis可以存储1/N的数据量),实现了容量的横向扩展。同时每台Redis还可以配一个从节点,这样就可以更好地保证数据的安全性

redis与分布式,redis,redis,分布式,数据库

 

集群的机制

插槽就是键的Hash计算后的一个结果,采用CRC16,能得到16个bit位的数据,也就是说算出来之后结果是0-65535之间,再进行取模

Redis key的路由计算公式:s = CRC16(key) % 16384

一个Redis集群包含16384个插槽,集群中的每个Redis 实例负责维护一部分插槽以及插槽所映射的键值数据

哈希结果的值是多少,就应该存放到对应维护的Redis下,比如Redis节点1负责0-25565的插槽,而这时客户端插入了一个新的数据a=10,a在Hash计算后结果为666,那么a就应该存放到1号Redis节点中。本质上就是通过哈希算法将插入的数据分摊到各个节点的

集群搭建

配置中开启集群模式

# cluster node enable the cluster support uncommenting the following:
#
cluster-enabled yes

接着把所有的持久化文件全部删除,所有的节点内容必须是空的

输入

redis-cli.exe --cluster create --cluster-replicas 1 127.0.0.1:6001 127.0.0.1:6002 127.0.0.1:6003 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003
#--cluster-replicas 1指的是每个节点配一个从节点
​

redis与分布式,redis,redis,分布式,数据库

 

默认分配的方案是6001/6002/6003都被选为主节点,其他的为从节点,直接输入yes同意方案即可

插入数据时,键计算出来的哈希值(插槽),若不归当前节点管,则无法插入,需要去管这个插槽的节点执行

也可以使用集群方式连接,这样无论在哪个节点都可以插入,只需要添加-c表示以集群模式访问

redis与分布式,redis,redis,分布式,数据库

 

输入cluster nodes命令来查看当前所有节点的信息

当一个主节点挂了,其从节点就可以晋升为主节点,再次启用原主节点,发现其变为现主节点的从节点,当两个节点都挂了,也就是说集群存在不可用的节点,会无法插入新的数据

Java连接到集群模式下的Redis

使用JedisCluster对象即可

public class Main {
    public static void main(String[] args) {
        //和客户端一样,随便连一个就行,也可以多写几个,构造方法有很多种可以选择
        try(JedisCluster cluster = new JedisCluster(new HostAndPort("127.0.0.1", 6003))){
            System.out.println("集群实例数量:"+cluster.getClusterNodes().size());
            cluster.set("a", "yyds");
            System.out.println(cluster.get("a"));
        }
    }
}

分布式锁

setnx key value #只有当指定的key不存在的时候,才能进行插入
#当客户端1设定a之后,客户端2使用setnx会直接失败,但使用set可以成功
#当客户端1删除a之后,客户端2使用setnx就会成功

某个服务加了锁但服务本身卡顿了或是直接崩溃了,那这把锁将无法释放了,因此还可以考虑加个过期时间

set a 666 EX 5 NX   #最后加一个NX表示是使用setnx的模式

问题1:一个服务放了一个键值对,由于资源紧张服务时间过长,键值对的过期时间先到了,而在第一个服务未结束时,第二个服务开启并存放了与第一个服务键值相同的数据,然后第一个服务完事了,就把第二个服务存放的键值对删了

只是添加过期时间,会出现这种把别人加的锁谁卸了的情况

解决方案:现在想保证任务只能删除自己加的锁,如果是别人加的锁是没有资格删的,所以可以吧a的值指定为任务专属的值,如果在主动删除锁的时候发现值不是当前任务指定的,那么说明可能是因为超时,其他任务已经加锁了

问题2:如果在超时之前那一刹那进入到释放锁的阶段,获取到值还是自己,但是在即将执行删除之前,由于超时机制导致被删除并且其他任务也加锁了,那么这时再进行删除,仍然会导致删除其他任务加的锁

本质还是因为锁的超时时间不太好衡量,如果超时时间能够设定地比较恰当,就可以避免这种问题了

解决方案:可以使用Redisson框架,它是Redis官方推荐的Java版的Redis客户端。Redisson内部提供了一个监控锁的看门狗,作用是在Redisson实例被关闭前,不断的延长锁的有效期,它提供了很多种分布式锁的实现

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.17.0</version>
</dependency>
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.75.Final</version>
</dependency>
// 注:这个锁是基于Redis的,不仅仅只可以用于当前应用,是能够垮系统的
public static void main(String[] args) {
    Config config = new Config();
    config.useSingleServer().setAddress("redis://127.0.0.1:6379");   //配置连接的Redis服务器,也可以指定集群
    RedissonClient client =  Redisson.create(config);   //创建RedissonClient客户端
    for (int i = 0; i < 10; i++) {
        new Thread(() -> {
            try(Jedis jedis = new Jedis("127.0.0.1", 6379)){
                RLock lock = client.getLock("testLock");    //指定锁的名称,拿到锁对象
                for (int j = 0; j < 100; j++) {
                    lock.lock();    //加锁
                    int a = Integer.parseInt(jedis.get("a")) + 1;
                    jedis.set("a", a+"");
                    lock.unlock();   //解锁
                }
            }
            System.out.println("结束!");
        }).start();
    }
}

如果用于存放锁的Redis服务器挂了,还是是会出问题的,这个时就可以使用RedLock,它的思路是,在多个Redis服务器上保存锁,只需要超过半数的Redis服务器获取到锁,那么就真的获取到锁了,这样就算挂掉一部分节点,也能保证正常运行文章来源地址https://www.toymoban.com/news/detail-517466.html

到了这里,关于redis与分布式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 分布式数据库架构

    对于mysql架构,一定会使用到读写分离,在此基础上有五种常见架构设计:一主一从或多从、主主复制、级联复制、主主与级联复制结合。 1.1、主从复制 这种架构设计是使用的最多的。在读写分离的基础上,会存在一台master作为写机,一个或多个slave作为读机。因为在实际的

    2024年02月10日
    浏览(50)
  • 分析型数据库:分布式分析型数据库

    分析型数据库的另外一个发展方向就是以分布式技术来代替MPP的并行计算,一方面分布式技术比MPP有更好的可扩展性,对底层的异构软硬件支持度更好,可以解决MPP数据库的几个关键架构问题。本文介绍分布式分析型数据库。 — 背景介绍— 目前在分布式分析型数据库领域,

    2023年04月14日
    浏览(62)
  • 分布式数据库HBase

    HBase是一个高可靠、高性能、 面向列 、可伸缩的分布式数据库,是谷歌BigTable的开源实现,主要用来存储非结构化和把结构化的松散数据。 HBase的目标是处理非常庞大的表,可以通过水平扩展的方式,利用 廉价计算机集群 处理由超过10亿行数据和数百万列元素组成的数据表。

    2024年02月09日
    浏览(57)
  • 【大数据】分布式数据库HBase

    目录 1.概述 1.1.前言 1.2.数据模型 1.3.列式存储的优势 2.实现原理 2.1.region 2.2.LSM树 2.3.完整读写过程 2.4.master的作用 本文式作者大数据系列专栏中的一篇文章,按照专栏来阅读,循序渐进能更好的理解,专栏地址: https://blog.csdn.net/joker_zjn/category_12631789.html?spm=1001.2014.3001.5482 当

    2024年04月27日
    浏览(48)
  • 分布式数据库-事务一致性

    version: v-2023060601 author: 路__ 分布式数据库的“强一致性”应该包含两个方面: serializability(串行) and linearizability(线性一致) ,上述图为“Highly Available Transactions: Virtues and Limitations”论文中对于一致性模型的介绍。图中箭头表示一致性模型之间的关系。对于异步网络上的分

    2024年02月08日
    浏览(53)
  • 分布式数据库NoSQL(二)——MongoDB 数据库基本操作

    MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。 MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 json 的

    2024年02月06日
    浏览(52)
  • 聊聊分布式 SQL 数据库Doris(三)

    在 Doris 的存储引擎规则: 表的数据是以分区为单位存储的,不指定分区创建时,默认就一个分区. 用户数据首先被划分成若干个分区(Partition),划分的规则通常是按照用户指定的分区列进行范围划分,比如按时间划分。 在每个分区内,数据被进一步的按照Hash的方式分桶,分

    2024年02月05日
    浏览(56)
  • 聊聊分布式 SQL 数据库Doris(一)

    MPP:Massively Parallel Processing, 即大规模并行处理. 一般用来指多个SQL数据库节点搭建的数据仓库系统. 执行查询的时候, 查询可以分散到多个SQL数据库节点上执行, 然后汇总返回给用户. Doris 作为一款开源的 MPP 架构 OLAP 高性能、实时的分析型数据库,能够运行在绝大多数主流的商

    2024年02月05日
    浏览(46)
  • 聊聊分布式 SQL 数据库Doris(六)

    此处的负载均衡指的是FE层的负载均衡. 当部署多个 FE 节点时,用户可以在多个 FE 之上部署负载均衡层来实现 Doris 的高可用。官方文档描述: 负载均衡 。 实现方式 实现方式有多种,如下列举。 开发者在应用层自己进行重试与负载均衡。 JDBC Connector 发现一个连接挂掉,就自

    2024年02月05日
    浏览(54)
  • 聊聊分布式 SQL 数据库Doris(二)

    Doris中,Leader节点与非Leader节点和Observer节点之间的元数据高可用和一致性,是通过bdbje(全称:Oracle Berkeley DB Java Edition)的一致性和高可用实现的。 元数据与同步流程 元数据主要存储四类数据: 用户数据信息. 包括数据库, 表的schema, 分片信息等 各类作业信息. 如导入作业, clo

    2024年02月05日
    浏览(68)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包