syncer.go
package mirror
import (
"github.com/coreos/etcd/clientv3"
"golang.org/x/net/context"
)
const (
batchLimit = 1000
)
// Syncer syncs with the key-value state of an etcd cluster.
type Syncer interface {
// SyncBase syncs the base state of the key-value state.
// The key-value state are sent through the returned chan.
SyncBase(ctx context.Context) (<-chan clientv3.GetResponse, chan error)
// SyncUpdates syncs the updates of the key-value state.
// The update events are sent through the returned chan.
SyncUpdates(ctx context.Context) clientv3.WatchChan
}
// NewSyncer creates a Syncer.
func NewSyncer(c *clientv3.Client, prefix string, rev int64) Syncer {
return &syncer{c: c, prefix: prefix, rev: rev}
}
type syncer struct {
c *clientv3.Client
rev int64
prefix string
}
func (s *syncer) SyncBase(ctx context.Context) (<-chan clientv3.GetResponse, chan error) {
respchan := make(chan clientv3.GetResponse, 1024)
errchan := make(chan error, 1)
// if rev is not specified, we will choose the most recent revision.
if s.rev == 0 {
resp, err := s.c.Get(ctx, "foo")
if err != nil {
errchan <- err
close(respchan)
close(errchan)
return respchan, errchan
}
s.rev = resp.Header.Revision
}
go func() {
defer close(respchan)
defer close(errchan)
var key string
opts := []clientv3.OpOption{clientv3.WithLimit(batchLimit), clientv3.WithRev(s.rev)}
if len(s.prefix) == 0 {
// If len(s.prefix) == 0, we will sync the entire key-value space.
// We then range from the smallest key (0x00) to the end.
opts = append(opts, clientv3.WithFromKey())
key = "\x00"
} else {
// If len(s.prefix) != 0, we will sync key-value space with given prefix.
// We then range from the prefix to the next prefix if exists. Or we will
// range from the prefix to the end if the next prefix does not exists.
opts = append(opts, clientv3.WithRange(clientv3.GetPrefixRangeEnd(s.prefix)))
key = s.prefix
}
for {
resp, err := s.c.Get(ctx, key, opts...)
if err != nil {
errchan <- err
return
}
respchan <- (clientv3.GetResponse)(*resp)
if !resp.More {
return
}
// move to next key
key = string(append(resp.Kvs[len(resp.Kvs)-1].Key, 0))
}
}()
return respchan, errchan
}
func (s *syncer) SyncUpdates(ctx context.Context) clientv3.WatchChan {
if s.rev == 0 {
panic("unexpected revision = 0. Calling SyncUpdates before SyncBase finishes?")
}
return s.c.Watch(ctx, s.prefix, clientv3.WithPrefix(), clientv3.WithRev(s.rev+1))
}
syncer.go的更多相关文章
- TiDB数据库 使用syncer工具同步实时数据
mysql> select campaign_id ,count(id) from creative_output group by campaign_id; rows min 44.23 se ...
- C#中级-常用多线程操作(持续更新)
一.前言 多线程操作一直是编程的常用操作,掌握好基本的操作可以让程序运行的更加有效.本文不求大而全,只是将我自己工作中常常用到的多线程操作做个分类和总结.平时记性不好的时候还能看看.本文参 ...
- Heartbeat+DRBD+MySQL高可用方案
1.方案简介 本方案采用Heartbeat双机热备软件来保证数据库的高稳定性和连续性,数据的一致性由DRBD这个工具来保证.默认情况下只有一台mysql在工作,当主mysql服务器出现问题后,系统将自 ...
- drdb
Distributed Replicated Block Device(DRBD)是一种基于软件的,无共享,复制的存储解决方案,在服务器之间的对块设备(硬盘,分区,逻辑卷等)进行镜像.DRBD工作在内 ...
- Linux 集群
html,body { } .CodeMirror { height: auto } .CodeMirror-scroll { } .CodeMirror-lines { padding: 4px 0 ...
- ZABBIX冗余架构构筑(Centos6.4+pacemaker+corosync+drbd)
基本构成: 用pacemaker+corosync控制心跳和资源迁移 用drbd同步zabbix配置文件和mysql数据库 所有软件都用yum安装至默认路径 主机的drbd领域挂载至/drbd,备机不 ...
- MySQL 系列(五) 多实例、高可用生产环境实战
MySQL 系列(五) 多实例.高可用生产环境实战 第一篇:MySQL 系列(一) 生产标准线上环境安装配置案例及棘手问题解决 第二篇:MySQL 系列(二) 史上最屌.你不知道的数据库操作 第三 ...
- 1 构建Mysql+heartbeat+DRBD+LVS集群应用系统系列之DRBD的搭建
preface 近来公司利润上升,购买了10几台服务器,趁此机会,把mysql的主从同步的架构进一步扩展,为了适应日益增长的流量.针对mysql架构的扩展,先是咨询前辈,后和同事探讨,准备采用Mysq ...
- linux 后台运行命令 nohup命令
转载:http://if.ustc.edu.cn/~ygwu/blog/archives/000538.html 2005年04月18日 简单而有用的nohup命令在UNIX/LINUX中,普通进程用 ...
随机推荐
- C语言有哪些鲜为人知的特性?
译注:本文摘编自 Quora 的一个热门问答贴. 请在linux系统下测试本文中出现的代码 Andrew Weimholt 的回复: switch语句中的case 关键词可以放在if-else或者是循 ...
- Mac OS 的属性列表文件plist装换
Mac OS系统自身包含有转换plist的工具:plutil.其中-p是以human可读方式显示plist文件,而convert就是转换参数,其中支持的格式有:xml,二进制和json.下面拿一个实际 ...
- azkaban报错记录
问题信息:Failed to build job executor for job o2o_get_file_ftp1Job type 'command ' is unrecognized. Coul ...
- 途牛java实习面试(失败)
一进去让自己介绍.简单介绍了一下.然后让我自己说说框架.问题太大一紧张卡住了. 然后面试官开始问,让我介绍多线程,我就简单介绍了多线程.然后问我有没有做过多线程的项目,我说没有. 问了MySQL的锁和 ...
- OSGI介绍
OSGI介绍 OSGI简介 OSGI (Open Service Gateway Initiative)联盟成立于1999 年,它是一个非盈利的国际组织,旨在建立一个开放的服务规范,为通过网络向设备提 ...
- Day4_闭包含数
闭包函数: 闭包函数是在作用域的前提下 闭包含数:定义在函数内部的函数,包含对外部作用域名字的引用,而不是对全局作用域名字的引用,那么该内部函数就称为闭包含数. eg: x=1 def f1(): x ...
- 【读书笔记】C++Primer---第二章
1.C++基本数据类型:字符型.整型.浮点型等: 2.算术类型如下表,下表只是表示C++要求的最小储存空间,但是一般编译器使用的都比所要求的储存空间大,以前类型所能表示的最大值也因机器的不同而有不同的 ...
- hadoop配置文件详解系列(二)-hdfs-site.xml篇
上一篇介绍了core-site.xml的配置,本篇继续介绍hdfs-site.xml的配置. 属性名称 属性值 描述 hadoop.hdfs.configuration.version 1 配置文件的 ...
- codeforces——961B. Lecture Sleep
本文为博主原创文章,未经允许不得转载. 我在csdn也同步发布了此文,链接 https://blog.csdn.net/umbrellalalalala/article/details/7989196 ...
- Java并发-线程安全性
首先了解一下多线程的概念 多线程:两段或以上的代码同时进行,多个顺序执行流. 并发和并行的区别 并发:做一下这个做一下那个. 并行:同时进行. 线程和进程的区别 进程:资源分配的基本单位,运行中的程序 ...