前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >聊聊claudb的MasterReplication

聊聊claudb的MasterReplication

原创
作者头像
code4it
修改于 2020-08-24 02:03:44
修改于 2020-08-24 02:03:44
15100
代码可运行
举报
文章被收录于专栏:码匠的流水账码匠的流水账
运行总次数:0
代码可运行

本文主要研究一下claudb的MasterReplication

MasterReplication

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/replication/MasterReplication.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class MasterReplication implements Runnable {private static final Logger LOGGER = LoggerFactory.getLogger(MasterReplication.class);private static final String SELECT_COMMAND = "SELECT";
  private static final String PING_COMMAND = "PING";
  private static final int TASK_DELAY = 2;private final DBServerContext server;
  private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();public MasterReplication(DBServerContext server) {
    this.server = server;
  }public void start() {
    executor.scheduleWithFixedDelay(this, TASK_DELAY, TASK_DELAY, TimeUnit.SECONDS);
  }public void stop() {
    executor.shutdown();
  }public void addSlave(String id) {
    getServerState().addSlave(id);
    LOGGER.info("new slave: {}", id);
  }public void removeSlave(String id) {
    getServerState().removeSlave(id);
    LOGGER.info("slave revomed: {}", id);
  }
​
  @Override
  public void run() {
    List<RedisToken> commands = createCommands();for (SafeString slave : getServerState().getSlaves()) {
      for (RedisToken command : commands) {
        server.publish(slave.toString(), command);
      }
    }
  }private List<RedisToken> createCommands() {
    List<RedisToken> commands = new LinkedList<>();
    commands.add(pingCommand());
    commands.addAll(commandsToReplicate());
    return commands;
  }private List<RedisToken> commandsToReplicate() {
    List<RedisToken> commands = new LinkedList<>();for (RedisToken command : server.getCommandsToReplicate()) {
      command.accept(new AbstractRedisTokenVisitor<Void>() {
        @Override
        public Void array(ArrayRedisToken token) {
          commands.add(selectCommand(token));
          commands.add(command(token));
          return null;
        }
      });
    }
    return commands;
  }private RedisToken selectCommand(ArrayRedisToken token) {
    return array(string(SELECT_COMMAND),
        token.getValue().stream().findFirst().orElse(string("0")));
  }private RedisToken pingCommand() {
    return array(string(PING_COMMAND));
  }private RedisToken command(ArrayRedisToken token) {
    return array(token.getValue().stream().skip(1).collect(toList()));
  }private DBServerState getServerState() {
    return serverState().getOrElseThrow(() -> new IllegalStateException("missing server state"));
  }private Option<DBServerState> serverState() {
    return server.getValue("state");
  }
}
  • MasterReplication实现了Runnable接口,其start方法调度执行自身的runnable,每隔2秒执行一次;其run方法先执行createCommands方法,然后遍历slaves,然后遍历commands,执行server.publish(slave.toString(), command);createCommands先添加ping命令,然后再添加commandsToReplicate;commandsToReplicate方法遍历server.getCommandsToReplicate(),遇到array方法时先添加select命令,再添加command命令,最后返回commands

getCommandsToReplicate

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/ClauDB.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ClauDB extends RespServerContext implements DBServerContext {//......
​
  @Override
  public ImmutableList<RedisToken> getCommandsToReplicate() {
    return executeOn(Observable.<ImmutableList<RedisToken>>create(observable -> {
      observable.onNext(getState().getCommandsToReplicate());
      observable.onComplete();
    })).blockingFirst();
  }//......}
  • getCommandsToReplicate方法执行的是getState().getCommandsToReplicate()

getCommandsToReplicate

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/DBServerState.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class DBServerState {private static final int RDB_VERSION = 6;private static final SafeString SLAVES = safeString("slaves");
  private static final DatabaseKey SLAVES_KEY = safeKey("slaves");
  private static final DatabaseKey SCRIPTS_KEY = safeKey("scripts");private boolean master = true;private final List<Database> databases = new ArrayList<>();
  private final Database admin;
  private final DatabaseFactory factory;private final Queue<RedisToken> queue = new LinkedList<>();public void append(RedisToken command) {
    queue.offer(command);
  }//......public ImmutableList<RedisToken> getCommandsToReplicate() {
    ImmutableList<RedisToken> list = ImmutableList.from(queue);
    queue.clear();
    return list;
  }//......}
  • getCommandsToReplicate方法会根据queue创建ImmutableList,然后清空queue;而append方法会添加command到queue

executeCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/ClauDB.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ClauDB extends RespServerContext implements DBServerContext {//......protected RedisToken executeCommand(RespCommand command, Request request) {
    if (!isReadOnly(request.getCommand())) {
      try {
        RedisToken response = command.execute(request);
        replication(request);
        notification(request);
        return response;
      } catch (RuntimeException e) {
        LOGGER.error("error executing command: " + request, e);
        return error("error executing command: " + request);
      }
    } else {
      return error("READONLY You can't write against a read only slave");
    }
  }private void replication(Request request) {
    if (!isReadOnlyCommand(request.getCommand())) {
      RedisToken array = requestToArray(request);
      if (hasSlaves()) {
        getState().append(array);
      }
      persistence.ifPresent(manager -> manager.append(array));
    }
  }
​
  @Override
  public void publish(String sourceKey, RedisToken message) {
    Session session = getSession(sourceKey);
    if (session != null) {
      session.publish(message);
    }
  }//......}
  • executeCommand方法除了执行command.execute,还会执行replication方法,它会在有slaves的条件将非readOnlyCommand追加到state;publish方法执行的是session.publish(message)传输给slave

小结

MasterReplication实现了Runnable接口,其start方法调度执行自身的runnable,每隔2秒执行一次;其run方法先执行createCommands方法,然后遍历slaves,然后遍历commands,执行server.publish(slave.toString(), command);createCommands先添加ping命令,然后再添加commandsToReplicate;commandsToReplicate方法遍历server.getCommandsToReplicate(),遇到array方法时先添加select命令,再添加command命令,最后返回commands

doc

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
T-SQL进阶:超越基础 Level 2:编写子查询
By Gregory Larsen, 2016/01/01 (首次发布于: 2014/01/29) 关于系列 本文属于进阶系列:T-SQL进阶:超越基础 跟随Gregory Larsen的T-SQL DML进阶系列,其涵盖了更多的高级方面的T-SQL语言,如子查询。 在您开始创建超出基本Transact-SQL语句的更复杂的SQL代码时,您可能会发现需要使用其他SELECT语句的结果来限制查询。 当在父Transact-SQL语句中嵌入SELECT语句时,这些嵌入式SELECT语句被称为子查询或相关子查询。
Woodson
2018/07/18
6.5K0
触发器
一:什么是触发器 触发器是一种响应特定事件的特殊类型的存储过程 insert update... drop alter...等事件都有相应的触发器 二:简单的触发器 下面一个例子是在插入或者修改记录的时候的一个触发器 其中inserted表是一个临时表 存储的是将要插入的信息 这个触发器的目的是检查将要插入的信息是否符合规定 (在product表里没有特殊的记录) 这个例子是check约束所不能解决的了的
liulun
2022/05/08
1.4K0
一定是最适合你的后端面试指南
不论是校招还是社招都避免不了各种面试、笔试,如何去准备这些东西就显得格外重要。不论是笔试还是面试都是有章可循的,我这个“有章可循”说的意思只是说应对技术面试是可以提前准备。 我其实特别不喜欢那种临近考试就提前背啊记啊各种题的行为,非常反对!我觉得这种方法特别极端,而且在稍有一点经验的面试官面前是根本没有用的。建议大家还是一步一个脚印踏踏实实地走。
后端技术探索
2019/07/19
1.5K1
一定是最适合你的后端面试指南
万字详文告诉你如何做 Code Review
作者:cheaterlin,腾讯 PCG 后台开发工程师 前言 作为公司代码委员会 golang 分会的理事,我 review 了很多代码,看了很多别人的 review 评论。发现不少同学 code review 与写出好代码的水平有待提高。在这里,想分享一下我的一些理念和思路。 为什么技术人员包括 leader 都要做 code review 谚语曰: 'Talk Is Cheap, Show Me The Code'。知易行难,知行合一难。嘴里要讲出来总是轻松,把别人讲过的话记住,组织一下语言,再
腾讯技术工程官方号
2020/06/18
4.2K0
牛客面经 |这可能不只是一篇面经
这可能不只是一篇面经 作者:_XiaoTeng_ 来源:牛客网 【这可能不只是一篇面经】 精 写了个显眼的标题,就真得说几句有用的话。 5月份一个很偶然的机会,加了叶神的微信,还收到了祝福。一激动就承诺说写篇最详细的面经分享给大家,毕竟用了这么久的牛客网,收获真的很大。 校招真的是段劳心伤神的经历,我把这一路的体会,写在秋招前,也许能给那些和我一样迷茫过,怀疑过,失落过的人一些帮助。 (这篇文章有点长,可能需要点耐心) 0. 写在之前 首先呢我的面试经历和一些面霸和收割机的大
java思维导图
2018/04/08
3.3K0
ggplot2的作者Hadley Wickham拿了"统计学界的诺贝尔奖"
|| 原文来源:统计之都 (https://mp.weixin.qq.com/s/dbVJoUtHk3ORrQbNp7IypQ)
生信宝典
2019/08/12
1.6K0
[Python从零到壹] 一.为什么我们要学Python及基础语法详解
欢迎大家来到“Python从零到壹”,在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界。所有文章都将结合案例、代码和作者的经验讲解,真心想把自己近十年的编程经验分享给大家,希望对您有所帮助,文章中不足之处也请海涵。
Eastmount
2021/02/05
6100
[Python从零到壹] 一.为什么我们要学Python及基础语法详解
从原理到策略算法再到架构产品看推荐系统 | 附Spark实践案例
作者 | HCY崇远 01 前言 本文源自于前阵子连续更新的推荐系统系列,前段时间给朋友整理一个关于推荐系统相关的知识教学体系,刚好自身业务中,预计明年初随着业务规模增长,估摸着又要启动推荐相关的项目了,所以也是趁机把相关的知识结构梳理了一遍。这这里重新做整理,并额外做了一些增减,让整体逻辑会更通顺一点。 整个文章的结构逻辑,先从推荐系统的基础知识结构讲起,然后由浅入深过渡到几个推荐策略算法上,并且为每个推荐策略算法提供一些简单的入门Spark案例代码,再从策略过渡到系统层级,包括数据架构、策略组合
CSDN技术头条
2018/02/06
2K0
从原理到策略算法再到架构产品看推荐系统 | 附Spark实践案例
还记得当年踏上信安之路的初衷吗
一年前在信安之路的交流群里做了一个活动:在我们这个信息安全的圈子里,渗透测试仅仅是安全中的一个很小的分支,虽说这个圈子的缺口很大,但是为什么一直补不上这个缺口呢?
信安之路
2019/03/12
2.4K0
程序员的英语学习指南
对程序员来说,“渣英语”可是限制自己更上一层楼的重要阻碍。不仅阅读最新英文研究与教程困难,去国际顶会与别人开口交流也成了问题。
量子位
2019/04/24
1.4K0
程序员的英语学习指南
fast.ai 机器学习笔记(四)
这个想法是我们有一些数据(x),然后我们对这些数据做一些操作,例如,我们用一个权重矩阵乘以它(f(x))。然后我们对这个结果做一些操作,例如,我们通过 softmax 或 sigmoid 函数处理它(g(f(x)))。然后我们对这个结果做一些操作,比如计算交叉熵损失或均方根误差损失(h(g(f(x))))。这将给我们一些标量。这里没有隐藏层。这有一个线性层,一个非线性激活函数是 softmax,一个损失函数是均方根误差或交叉熵。然后我们有我们的输入数据。
ApacheCN_飞龙
2024/02/11
1720
fast.ai 机器学习笔记(四)
爱英文的程序员运气不会太差:史上最全程序员英语进阶指南
经作者授权转载 作者 | han 你渴望尝试新的技术: GraphQL, Figma, MobX; 你耐心等待优秀的中文翻译: 等待,等待,还是等待; 你来者不拒地寻找提高英语水平的最佳方法: 疯狂英语,红宝书,玄学; 我这里有本“葵花宝典”…… 英语水平等级示意图: 本图主要参考 http://www.coe.int/en/web/common-european-framework-reference-languages/table-1-cefr-3.3-common-reference-levels-g
大数据文摘
2018/05/24
3.7K0
JAVA高频216道面试题+答案!!面试必备
  在本篇文章开始之前,我想先来回答一个问题:我为什么要写这样一篇关于面试的文章?原因有三个:第一,我想为每一个为梦想时刻准备着的“有心人”,尽一份自己的力量,提供一份高度精华的 Java 面试清单;第二,目前市面上的面试题不是答案不准确就是内容覆盖面太窄,所以提供一份经典而又准确的面试题是非常有必要的;第三,本文会对部分面试题提供详细解读和代码案例,让读者知其然并知其所以然,从而学到更多的知识。
陈哈哈
2021/10/13
1.2K0
ffmpeg 入门_python入门笔记
最近在读《FFmpeg从入门到精通》这本书,结合着雷神的博客,学习音视频的知识~ 在学习的过程中,也记录了一些摘要。因为是边看边记的,所以一些要点在看到后面的时候,需要反过来整理前面的。我用有道云笔记写的markdown没法加图片,所以就先把这部分发了出来。后续会针对内容和排版一步步的优化,如果你被这凌乱的内容辣到了眼睛,请谅解哈哈哈~
全栈程序员站长
2022/08/03
1.8K0
ffmpeg 入门_python入门笔记
AI智能体(四)
以往,我们都是直接跟大模型进行交互,没有办法系统的实现记忆。langchain给出了一个系统级的解决方案,如上图中,用户提出问题,系统会先在存储器(如上图中的redis)中查询相关的文档返回系统,系统会带着用户的问题以及查询到的文档碎片一起提交给大模型,然后再将答案返回给用户。其中存储器充当了大脑记忆的部分。在上图的左下角,就是我们之前说的各种文档(pdf,word,excel等)通过向量化后存储进存储器。比起直接向大模型提问,langchain相当于多了一个外挂系统。
算法之名
2025/02/06
1720
AI智能体(四)
高性能 MySQL 第四版(GPT 重译)(三)
在前几章中,我们解释了模式优化和索引,这对于高性能是必要的。但这还不够——您还需要设计良好的查询。如果您的查询不好,即使是设计最佳的模式和索引也不会表现良好。
ApacheCN_飞龙
2024/03/20
2420
高性能 MySQL 第四版(GPT 重译)(三)
一篇文带你从0到1了解建站及完成CMS系统编写
文章为从0到1了解内容管理系统搭建与编写,由于一篇文章内容篇幅过长,文章内容经过压缩,该项目中相同逻辑的实现只以一个实例作为描述,主要以核心关键功能的开发作为主要的讲解步骤。如有想学习完整内容系统编写可在留言区留言,我会尽快完成完整版的实战教程发布。谢谢。本篇不涉及vue、nodejs的前端框架。
1_bit
2020/10/29
3.3K0
一篇文带你从0到1了解建站及完成CMS系统编写
流畅的 Python 第二版(GPT 重译)(二)
我们在所有的 Python 程序中都使用字典。即使不是直接在我们的代码中,也是间接的,因为dict类型是 Python 实现的基本部分。类和实例属性、模块命名空间和函数关键字参数是内存中由字典表示的核心 Python 构造。__builtins__.__dict__存储所有内置类型、对象和函数。
ApacheCN_飞龙
2024/05/24
4450
流畅的 Python 第二版(GPT 重译)(二)
2018:春来秋去,往事知何处(上)
去年 12 月的某个夜晚,在部署服务的无聊时光里,我突然想翻看自己一年来的朋友圈,看看有哪些有趣的事情。结果那夜一发不可收拾,扫了半年的朋友圈,一直读到凌晨三点半还意犹未尽(毕竟五点半就要起床了,觉还是要象征性地睡一下)。我把一些有意思的内容摘录了下来,没事的时候,就补两句评语,就像在跟去年的自己对话 —— 这可能也算程序员级宅男的恶趣味了。
tyrchen
2019/03/07
1.4K0
2018:春来秋去,往事知何处(上)
牛逼!Java 从入门到精通,超全汇总版
其实学习 Java 学到什么程度算是精通,这个其实没有盖棺定论的,也不是说你拿个年薪几十万的 offer 就可以自诩精通了。另外,每当面试的时候简历上填个精通 offer 的家伙我就觉得很搞笑,没有几个熬得过开出门左拐的命运。但是我认为,如果市面上这些资料、书籍你都啃的差不多,你能在所有的 Java 程序员中跻身前 0.1% 的话,你就可以达到”精通” 这个阶段了,因为没人比你强了,你当然是精通了。
全栈程序员站长
2022/07/02
2.4K0
牛逼!Java 从入门到精通,超全汇总版
推荐阅读
相关推荐
T-SQL进阶:超越基础 Level 2:编写子查询
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验