干货 | 携程Redis跨IDC多向同步实践

京东科技Redis跨数据中心双向同步优化实践 一、背景 公司基于业务发展以及战略部署,需要实现在多个数据中心单元化部署,一方面可以实现多数据中心容灾,另外可以提升用户请求访问速度。需要保证多数据中心容灾或者实现用户就近访问的话,需要各个数据中心拥有一致的全量数据,如果真正实现用户就近读写,也就是实现真正的业务异地多活,数据同步是异地多活的基础,这就需要多数据中心间数据能够双向同步。 二、原生redis遇到的问题 1、不支持双主同步 原生redis并没有提供跨机房的主主同步机制,仅支持主从同步;如果仅利用redis的主从数据同步机制,只能将主节点与从节点 阅读详情

作者简介

祝辰,携程框架架构研发部资深研发工程师,主要负责Redis跨站点容灾方面的工作, 目前致力于研究分布式系统中的一致性问题以及相关理论和解决方案。此前曾就职于EMC混合云部门。对底层技术比较感兴趣,乐于研究操作系统和各种数据库的实现思路。

一、前言

跨DC(数据中心)的数据同步是企业提升容灾实力的必备手段。随着携程业务向海外发展的速度越来越快,应用架构能够快速全球部署的能力也愈发重要。对于服务而言,我们可以尽量做到无状态的部署架构,来达到灵活拓展,快速部署的目的,比如 server-less。

然而,对于业务应用来讲,大量的业务逻辑是有状态的,仅仅做到服务的灵活拓展还不够,需要数据也拥有多站点共享的能力。

携程在一年前已经可以实现 Redis 单向跨区域同步,从上海将数据复制到美国加州,德国法兰克福,以及新加坡等众多海外站点,延迟稳定在 180ms左右,支持单个Redis 5MB/s 的传输带宽。

关于跨公网传输以及跨区域单向复制,详情参考这篇文章:携程Redis海外机房数据同步实践。

但是,技术人的目标就是不断突破自己。在Redis出海同步一年之后,业务上有了新的需求:能否在每个站点都可以独立地写入和读取,所有数据中心之间互相同步,而跨区域复制的一致性等问题,也可以由底层存储来解决?

单向同步的 Redis 固然可以解决问题,然而,大量的海外数据需要先回流上海,再从上海同步至各个数据中心,这一来一去, 不仅给业务开发带来了额外的复杂性和代码的冗余性,也给数据本身的时效性以及跨区域传输的费用带来了问题(携程的数据回源需要走专线,而 Redis 同步通过公网传输,由携程的框架中间件 - XPipe 来解决跨公网传输的安全和不稳定性因素)。[1]

二、技术选型

所以,我们需要的是一个分布式的Redis存储,能够实现跨区域多向同步。面对大型分布式系统,不免要讨论CAP理论,在跨区域多活的场景下如何取舍?

显然P(网络分区)是首要考虑因素。其次,跨区域部署就是为了提高可用性,而且对于常见的一致性协议,不管是2PC、Paxos还是raft,在此场景下都要做跨区域同步更新,不仅会降低用户体验,在网络分区的时候还会影响可用性。

对于Redis这种毫秒级相应的数据库,应用希望能够在每个站点都可以“如丝般顺滑”地使用,因此C必定被排在最后。

那是不是C无法被满足了呢?事实并非如此,退而求其次,最终一致也是一种选择。经过调研,我们决定选用“强最终一致性”的理论模型来满足一致性的需求。[2]

关于“最终一致性”(Eventually Consistency) 和“强最终一致性”(Strong Eventually Consistency),大家可以参考 wiki 百科给出的释义:

(Strong Eventually Consistency) Whereas eventual consistency is only a liveness guarantee (updates will be observed eventually), strong eventual consistency (SEC) adds the safety guarantee that any two nodes that have received the same (unordered) set of updates will be in the same state. If, furthermore, the system is monotonic, the application will never suffer rollbacks.


三、问题

有了目标,自然是开始计划和设计,那么在开始之前有什么问题呢?


3.1 跨数据中心双向同步共同的问题

各种数据库在设计双向数据同步时,均会遇到的问题:

1)复制回源:A -> B -> A

数据从 A 复制到 B,B 收到数据后,再回源复制给 A 的问题。

2)环形复制:A -> B -> C -> A

我们可以通过标记来解决上一问题,然而系统引入更多节点之后,A 发送到 B 的数据,可能通过 C 再次回到 A。

3)数据一致性

网络传输具有延迟性和不稳定性,多节点的并发写入会造成数据不一致的问题。

4)同步时延(鉴于是跨国的数据同步,这一项我们先忽略)


3.2 Redis 的问题

1)Redis 原生的复制模型,是不能够支持Multi-Master的理论架构的。

开源版的 Redis 只能支持 Master-Slave 的架构,并不能支持 Redis 之间互相同步数据。

2)Redis 特殊的同步方式(全量同步+增量同步),给数据一致性带来了更多挑战。

Redis 全量同步和增量同步都基于 replicationId + offset 的方式来做,在引入多个节点互相同步之后,如何对齐互相之间全量同步和增量同步的 offset 是一个巨大的问题。

3)同时支持原生的 Master-Slave 系统

在新版系统上,同时兼容现存的 Master-Slave 架构,两种同步方式和策略的异同,也带来了新的挑战。


四、解决方案

由于篇幅的限制,这里只对数据一致性的解决方案做下介绍,对于分布式系统或者是双向同步感兴趣的同学,可以关注我们后续的技术文章和技术大会。


4.1 一致性的解决方案

CRDT(Conflict-Free Replicated Data Type)[3] 是各种基础数据结构最终一致算法的理论总结,能根据一定的规则自动合并,解决冲突,达到强最终一致的效果。

2012年CAP理论提出者Eric Brewer撰文回顾CAP[4]时也提到,C和A并不是完全互斥,建议大家使用CRDT来保障一致性。自从被大神打了广告,各种分布式系统和应用均开始尝试CRDT,redislabs[5]和riak[6]已经实现多种数据结构,微软的CosmosDB[7]也在azure上使用CRDT作为多活一致性的解决方案。

携程的框架部门最终也选择站在巨人的肩膀上,通过 CRDT 这种数据结构,来实现自己的Redis跨区域多向同步。

4.2 CRDT

CRDT 同步方式有两种:

1)state-based replication 

发送端将自身的“全量状态”发送给接收端,接收端执行“ merge” 操作,来达到和发送端状态一致的结果。state-base replication 适用于不稳定的网络系统,通常会有多次重传。要求数据结构能够支持 associative(结合律)/commutative(交换律)/idempotent(幂等性)。

2)operation-based replication 

发送端将状态的改变转换为“操作”发送给接收端,接收端执行“update”操作,来达到和发送端状态一直的结果。op-based replication 只要求数据结构满足 commutative 的特性,不要求 idempotent(大家可以想一想为什么)。op-based replication 在接收到 client 端的请求时,通常分为两步进行操作:

a. prepare 阶段:将 client 端操作转译为CRDT的操作;

b. effect 阶段:将转译后的操作 broadcast 到其他 server;

两者之间在实现上,界限比较模糊。一方面,state-based replication可以通过发送 delta 减少网络流量,从而做到和 op-based replication 比较接近的效果;另一方面,op-based replication 可以通过发送 compact op-logs 将操作全集发送过去,来解决初始化的时候同步问题,从而达到类似于 state-based replication 的效果。

我们的系统需要借助两种同步方式,以适用于不同的场景中:

1) state-based replication 通常是基于“全量状态”进行同步,这样的结果是造成的网络流量太大,且同步的效率低下。在同步机制已经建立的系统中,我们更倾向于使用 op-based replication,以达到节省流量和快速同步的目的。

2) op-based replication 是基于 unbounded resource 的假设上进行论证的学术理念,在实践过程中,不可能有无限大的存储资源,将某个站点的全部数据缓存下来。

这样就带来一个问题,如果新加节点或者网络断开过久时,我们的存储资源不足以缓存所有值钱的操作,从而使得复制操作无法进行。此时,我们需要借助 state-based replication 进行多个站点之间,状态的merge操作。


4.3 CRDT 的数据结构

Redis 的 String 类型对应的操作有 SET, DEL, APPEND, INCRBY 等等,这里我们只讲一下SET操作(INCRBY 会是不同的数据类型)。


Register

先来讲一下,CRDT理论中如何处理Redis String 类型的同步问题。

Redis的String类型对应于CRDT里面的Register数据结构,对应的具体实现有两种比较符合我们的应用场景:

  • MV(Multi-Value) Register:数据保留多份副本,客户端执行GET操作时,根据一定的规则返回值,这种类型比较适合INCRBY 的整型数操作。

  • LWW(Last-Write-Wins) Register:数据只保留一份副本,以时间戳最大的那组数据为准,SET操作中,我们使用这种类型。

还记得上文提到的两种不同的同步方式么,关于两种不同的同步方式,对于LWW Register,实现方式会稍有不同。


Op-based LWW Register [8]

State-based LWW Register [8]

4.4 CRDT Register 在 Redis 中的落地

讲完了 CRDT 的传输类型和一个基本的数据结构,那么具体这样的理论是如何落地到 Redis 中间的呢?

在最终的实现中,我们采用了OR-Set(Observed-Remove Set) + LWW(Last-Write-Wins) Register 来实现 Redis 中的 String 操作。


4.4.1 Redis K/V

以下是理论上的数据结构,并不是 redis 中真正的结构体,仅仅作为说明使用。

struct CRDT.Register {       string key;       string val;       TAG delete-tag;       int timestamp; }

1)key 既是SET操作中的 key

2)val 用来存储相应的 value

3)delete-tag 是逻辑删除的标记位,具体的理论来源是 OR(Observed-Remove) Set

4)timestamp 用于LWW(Last Write Wins)机制,来解决并发冲突

由于目前我们的多写 Redis 还没有开源,这里我们拿 Java 程序举个栗子[9] 详细可以访问 github。

LWW Register

processCommand 是这个 CRDT 框架的核心函数,基本定义了每一种类型,是如何进行 merge/update 等操作的。 

在这里我们可以看到,每一个 command 过来时,会携带一个自身的时钟,由本地的程序进行判定,如果时钟符合偏序(partial ordered),就进行 merge 操作,并储存元素。

javapublic class LWWRegister extends AbstractCrdt<LWWRegister, LWWRegister.SetCommand> {
private T value;private StrictVectorClock clock;
public LWWRegister(String nodeId, String crdtId) { super(nodeId, crdtId, BehaviorProcessor.create()); this.clock = new StrictVectorClock(nodeId);}

protected Option<SetCommand<T>> processCommand(SetCommand<T> command) { if (clock.compareTo(command.getClock()) < 0) { clock = clock.merge(command.getClock()); doSet(command.getValue()); return Option.of(command); } return Option.none();}

public T get() { return value;}
public void set(T newValue) { if (! Objects.equals(value, newValue)) { doSet(newValue); commands.onNext(new SetCommand<>( crdtId, value, clock )); }}
private void doSet(T value) { this.value = value; clock = clock.increment();}
}

OR-SET

而 Observed-Remove SET 相较 LWW-Register 就复杂一些,主要涉及两个概念,一个是正常的原生储存的地方,在Set<Element<E>> elements中。而另一个重要的概念,是 tombstone(墓地),用来存放会删除的元素Set<Element<E>> tombstone OR-SET 的 tombstone,就可以解决并发删除的问题,而 LWW-Register 则可以解决并发添加的问题。

java ublic class ORSet extends AbstractSet implements Crdt<ORSet, ORSet.ORSetCommand> /*, ObservableSet */ {private final String crdtId;private final Set<Element<E>> elements = new HashSet<>();private final Set<Element<E>> tombstone = new HashSet<>();private final Processor<ORSetCommand<E>, ORSetCommand<E>> commands = ReplayProcessor.create();
public ORSet(String crdtId) { this.crdtId = Objects.requireNonNull(crdtId, "Id must not be null");}
@Overridepublic String getCrdtId() { return crdtId;}
@Overridepublic void subscribe(Subscriber<? super ORSetCommand<E>> subscriber) { commands.subscribe(subscriber);}
@Overridepublic void subscribeTo(Publisher<? extends ORSetCommand<E>> publisher) { Flowable.fromPublisher(publisher).onTerminateDetach().subscribe(command -> { final Option<ORSetCommand<E>> newCommand = processCommand(command); newCommand.peek(commands::onNext);
});}
private Option<ORSetCommand<E>> processCommand(ORSetCommand<E> command) { if (command instanceof AddCommand) { return doAdd(((AddCommand<E>) command).getElement())? Option.of(command) : Option.none(); } else if (command instanceof RemoveCommand) { return doRemove(((RemoveCommand<E>) command).getElements())? Option.of(command) : Option.none(); } return Option.none();}
@Overridepublic int size() { return doElements().size();}
@Overridepublic Iterator<E> iterator() { return new ORSetIterator();}
@Overridepublic boolean add(E value) { final boolean contained = doContains(value); prepareAdd(value); return !contained;}
private static <U> Predicate<Element<U>> matches(U value) { return element -> Objects.equals(value, element.getValue());}
private synchronized boolean doContains(E value) { return elements.parallelStream().anyMatch(matches(value));}
private synchronized Set<E> doElements() { return elements.parallelStream().map(Element::getValue).collect(Collectors.toSet());}
private synchronized void prepareAdd(E value) { final Element<E> element = new Element<>(value, UUID.randomUUID()); commands.onNext(new AddCommand<>(getCrdtId(), element)); doAdd(element);}
private synchronized boolean doAdd(Element<E> element) { return (elements.add(element) | elements.removeAll(tombstone)) && (!tombstone.contains(element));}
private synchronized void prepareRemove(E value) { final Set<Element<E>> removes = elements.parallelStream().filter(matches(value)).collect(Collectors.toSet()); commands.onNext(new RemoveCommand<>(getCrdtId(), removes)); doRemove(removes);}
private synchronized boolean doRemove(Collection<Element<E>> removes) { return elements.removeAll(removes) | tombstone.addAll(removes);}
}
4.4.2 用户视角

正常同步的场景

Data Type: Strings
Use Case: Common SETs Conflict Resolution: None

并发冲突的场景

Data Type: Strings
Use Case: Concurrent SETs
Conflict Resolution: Last Write Wins (LWW)

五、未完待续

由于篇幅限制,我们详细介绍了 CRDT 同步的理论基础以及一个Redis 的 K/V 数据结构在 CRDT 中是如何展现出来的。对 CRDT 或分布式数据库感兴趣的同学,请关注携程的公众号,也可以支持一下我们目前已经开源的的redis同步产品 -- XPipe (https://github.com/ctripcorp/x-pipe)。


附录

[1] 携程Redis海外机房数据同步实践

[2] CRDT——解决最终一致问题的利器

[3] CRDT: 

https://hal.inria.fr/inria-00609399/document

[4] Eric Brewer: 

https://www.infoq.com/articles/cap-twelve-years-later-how-the-rules-have-changed

[5] redislabs, Developing Applications with Geo-replicated CRDBs on Redis Enterprise Software(RS): https://redislabs.com/redis-enterprise-documentation/developing/crdbs/

[6] riak: 

https://docs.basho.com/riak/kv/2.0.0/developing/data-types/

[7] cosmosDB: 

https://docs.microsoft.com/en-us/azure/cosmos-db/multi-region-writers

[8] A comprehensive study of Convergent and Commutative Replicated Data Types(https://links.jianshu.com/go?to=http%3A%2F%2Fhal.upmc.fr%2Ffile%2Findex%2Fdocid%2F555588%2Ffilename%2Ftechreport.pdf)

[9] CRDT Java: 

https://github.com/netopyr/wurmloch-crdt

【推荐阅读】

Redis部署方式(0)四种部署方式介绍 主从模式是三种模式中最简单的,在主从复制中,数据库分为两类:主数据库(master)和从数据库(slave)。- slave挂了不影响其他slave的读和master的读和写,重新启动后会将数据从master同步过来;- master挂了以后,不影响slave的读,但redis不再提供写服务,master重启后redis将重新对外提供写服务;部署、Redis哨兵模式部署、Cluster集群模式部署,后面三种(redis的四种部署方式: Redis单机模式部署、数据丢失----大灾难。开启多Redis进程。 阅读详情

相关推荐

保姆级教程:用YOLOv5s搞定钢材表面缺陷检测,从数据集NEU-DET到模型部署全流程

本文提供了一份详细的YOLOv5s钢材表面缺陷检测教程,涵盖从NEU-DET数据集处理到模型部署的全流程。针对工业环境中的实际限制,如计算资源有限和标注样本少等问题,提供了优化方案和实用技巧,帮助开发者快速实现高效的钢材缺陷检测系统。

weixin_30568591的博客 464

干货 | 五大实例详解,携程 Redis 跨机房双向同步实践

作者简介 Nick,携程软件技术专家,关注分布式数据存储以及操作系统内核。 前言 在《携程 Redis 跨 IDC 多向同步实践》一文曾和大家分享过携程在 Redis 双向同步方面的心得,简单介绍了实现一个 Redis 双向同步系统中可能面临的问题,以及其中一种问题(分布式一致性)的部分处理方案 -- CRDT(Conflict-free ReplicatedData Types)。本文将进一步阐述在具体设计和落地过程中的一些细节, 希望对大家能够有所帮助。包括: Cycle Break -.

勇往直前的专栏 1163

ESP32 CAM使用教程(入门级)

串口被占用,可以关闭其他使用到串口的界面;先将手机也连上wifi,然后使用手机浏览器打开这个IP地址,注意手机连接的wifi需要和开发板的wifi一致,也就是程序里自己修改的那个wifi,否则无法打开IP地址;将开发板连接到电脑,点击点击工具→端口,然后选择自己实际接的COM口,不清楚COM口的可以打开电脑设备管理器查看一下,插拔设备看看哪个COM口会刷新就是哪个COM口;安装好esp32库之后,点击工具→开发板→esp32→AI Thinker ESP32-CAM,型号要仔细找找,不要选错了;

qq_34426854的博客 2万+

redis异地多活理论基础之CRDT

随着服务规模的扩大, 为了提升系统的容灾能力以及性能的要求, 会将...

weixin_33969116的博客 2241

Carla-编译CarlaUE4提示HoloLens.Automation项目缺少Windows程序集?

编译CarlaUE4提示HoloLens.Automation项目缺少Windows程序集?不妨看看这个!

DSK_981029的博客 2573

从零构建:如何在VSCode中为HBuilderX迁移的UniApp项目搭建TypeScript支持环境

本文详细指导如何将HBuilderX中的UniApp项目迁移至VSCode并搭建TypeScript支持环境。通过pnpm包管理器初始化项目、配置tsconfig.json和vite.config.ts文件,实现工程化迁移与TypeScript深度集成,提升开发效率和代码质量。

book8的博客 1050

Redis 如何实现跨数据中心数据同步

在规划跨数据中心的数据同步时,必须仔细评估网络延迟、带宽限制以及潜在的安全风险等因素,并选择最适合自身环境的技术方案。此外,还需考虑到维护和监控的成本,确保系统的稳定性和可靠性。Redis 实现跨数据中心数据同步可以通过多种方式来完成,主要取决于具体的使用场景、性能要求和容错需求。

Pmyx_wyh的博客 927

避坑指南:用逐飞开源库驱动MT9V03X摄像头时容易忽略的3个细节(附TFT显示优化技巧)

本文详细解析了在智能汽车竞赛中使用MT9V03X摄像头(总钻风)时常见的硬件连接、图像采集和TFT显示优化问题。重点介绍了逐飞开源库中容易被忽略的三个关键细节,包括电源管理、看门狗设置和中断优先级配置,并提供了针对IPS200和TFT180显示屏的优化技巧,帮助参赛队伍提升图像处理效率和显示质量。

study的专栏 743

五大实例详解,携程 Redis 跨机房双向同步实践

前言 在《携程 Redis 跨 IDC 多向同步实践》一文曾和大家分享过携程在 Redis 双向同步方面的心得,简单介绍了实现一个 Redis 双向同步系统中可能面临的问题,以及其中一种问题(分布式一致性)的部分处理方案 -- CRDT(Conflict-free ReplicatedData Types)。本文将进一步阐述在具体设计和落地过程中的一些细节, 希望对大家能够有所帮助。包括: Cycle Break -- 如何打破盗梦空间的无限循环 Last Write Wins & Vecto

hellozhxy的博客 1896

离散数学期末复习笔记【精华版】

文章目录前言一、????理逻辑1. 命题逻辑2. 等值演算3. 主合取范式、主析取范式4. 【题】推理证明5. 辖域、自由变元、约束变元二、????合1. 环和、环积,幂集,笛卡尔乘积三、 ????????关系1. 自反、对称、传递2&3. 合成运算,逆关系、闭包4. 哈斯图、上下界、偏序5. 等价关系、划分四、????1. 幺元(么元、单位元)、零元、逆元,半群、群、阿尔贝群、独异点、循环独异点2. 【题】由表判断3. 【题】证明五、????论1. 简单图、平凡图、多重图、子图、补图、出度、入度、

林大夕可的博客 17万+

王炸联动!OpenClaw 对接微信 / 企业微信保姆级教程,AI 办公效率翻倍

《OpenClaw对接微信/企业微信全指南》摘要:本文提供开源AI智能体OpenClaw与微信生态的完整对接教程。核心内容包括企业微信配置四步法(获取凭证、修改配置、重启服务、验证对接)和个人微信通过企业微信插件的一键打通方案。对接后支持微信/企微发指令AI秒执行、群聊机器人、文件同步等高效办公场景,并附常见问题排查代码。教程强调配置简单(全程可复制代码)、适用广泛(个人/团队场景),实现沟通与AI协作的无缝衔接。文末包含端口放行等实用命令,助力用户快速实现移动端AI办公。(149字)

2501_93651177的博客 582

滚雪球学Redis[7.4讲]:Redis在分布式系统中的应用:微服务与跨数据中心策略

在上一期【7.3 Redis在排行榜系统中的应用】中,我们探讨了如何利用Redis的Sorted Set数据结构构建一个高效的排行榜系统,并讨论了动态更新与大规模数据下的性能优化方案。通过Redis的轻量级、高性能特点,排行榜系统不仅能实时更新,还能在大数据量下保持查询的高效性。排行榜系统只是Redis众多应用场景之一,Redis的强大之处还体现在分布式系统的应用中。在如今以微服务架构为主导的分布式系统中,Redis不仅能作为缓存,还能承担服务注册配置中心等关键角色。

**My Coding Family** 1578

103:vue+cesium 设置球体水部分颜色为黄色

本示例在 Vue + cesium 项目中设置球体水部分颜色为黄色。这里的操作是将球体内部设置为空的,在地球内部添加一个黄色的圆球,这样水的部分就被突出出来了。直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果.

大剑师兰特的GIS世界 623

干货 | 携程光网络抵御光缆中断实践

作者简介Lightworker,携程网络技术专家,关注光纤通信、DCI传输技术领域。一、背景光传输网络(简称OTN)是一种基于光纤技术的通信网络。它利用光纤作为传输介质,将信息以光的形式进行传输。其凭借DWDM(密集型波分复用)技术以及保护倒换技术,可以实现大带宽、低延迟、高可靠的数据传输,因此广泛应用于多个数据中心互联场景。国内外大型互联网公司通过租用运营商光纤自建传输网络,能够大大降低IDC之...

携程技术 4932

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

干货 | 携程酒店搜索引擎AWS上云实践

作者简介宮娴,携程高级后端开发工程师;Spike,携程高级后端开发专家。随着携程国际化业务的快速推进,搜索引擎作为用户体验中至关重要的一环,上云变得志在必行。本文主要分享酒店搜索引擎迁移AWS的探索与实践过程,内容将涵盖一个HTTP请求的全链路处理过程:包括从APP发出请求到网关,再到内网错综复杂的微服务,最后到所依赖的各种持久化存储。一、微服务架构带来的挑战这次上云的...

携程技术 2786

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

干货 | 分布式数据库TiDB在携程的实践

原文来源: https://tidb.net/blog/31806a87 ...

TiDB 社区干货传送门 350

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

干货 | 携程容器偶发性超时问题案例分析(一)

作者简介李剑,携程系统研发部技术专家,负责Redis和Mongodb的容器化和服务化工作,喜欢深入分析系统疑难杂症。前言随着携程的应用大规模在生产上用容器部署,各种上规模的问题都慢慢浮现,其中比较难定位和解决的就是偶发性超时问题,下面将分析目前为止我们遇到的几种偶发性超时问题以及排查定位过程和解决方法,希望能给遇到同样问题的小伙伴们以启发。问题描述某一天接到用户报障说,Redis集群有超时现象发生...

携程技术 1592

干货 | 计算密集型服务的负载均衡策略

作者简介罗茂林,携程国际机票后台研发总监,主要负责国际机票引擎的研发工作。致力于系统性能优化和研发效率提升。一般情况下,在计算密集型服务中,即使处理单个请求也需要使用到服务器的所有CP...

携程技术 1182

Apollo- 全生命周期配置管理:从开发到生产的配置治理落地

选型从来不是比功能列表,而是比治理纵深与工程友好度。维度ApolloNacos(配置模块)Consul KV环境隔离粒度✅ 原生支持DEVTESTPRO等多环境命名空间,且同一 AppID 下不同环境完全隔离互不可见⚠️ 依赖 namespace + group + profile 多层组合,易混淆⚠️ 仅靠切换,无服务端环境强制校验❌ 无环境概念,全靠 key 命名约定配置发布原子性 & 回滚✅ 单次发布即全量生效(强一致性),支持秒级回滚至任意历史版本(带操作人、时间、原因)

千淘万漉虽辛苦,吹尽狂沙始到金 1万+

Redis跨机房双向同步实践

为什么需要异地多活? 如:Redis\Mysql上海机房A、B ,A为主机房 ,B为从机房,为的就是同步A机房数据,防止A机房断网等原因,无法为系统提供服务,做的容灾备用方案,同一个机房内 master节点挂了 slave节点可以通过哨兵模式等其他选主方案,重新选出新的master节点,继续为应用系统提供服务,但是如果A机房整个机房瘫痪了,此时还得保证Redis\Mysq继续为应用系统提供服务,那么就想到了,机房互相备份方案,比如千岛湖的机房B是上海机房A的备份存储,A机房挂了,B机房继续为应用系统提.

luzhensmart的专栏 1万+

72小时不宕机:Jedis跨数据中心异地多活架构实战指南

在当今分布式系统架构中,确保服务的高可用性和数据一致性是开发者面临的核心挑战。Jedis作为Redis官方推荐的Java客户端,提供了强大的跨数据中心异地多活解决方案,帮助企业构建72小时不宕机的高可用系统。本文将详细介绍如何利用Jedis实现跨数据中心的异地多活架构,确保业务在极端情况下仍能持续运行。 ## 什么是Jedis异地多活架构? Jedis异地多活架构是指通过配置多个Redis集群

gitblog_00105的博客 398

ETLCloud+携程实现高效数据同步

它为用户提供了一站式的数据集成平台,帮助实现数据的自动同步和转换,使数据在不同系统之间流动起来,进而促进业务的发展和创新。通过简单的拖拽操作,您可以创建、配置和管理数据抽取、转换和加载的任务,实现数据的自动同步和转换。:传统的与携程开放平台对接需要编写大量的代码,而使用ETLCloud,您无需编写繁琐的代码,只需通过配置和设置来实现与携程开放平台的集成。酒店:提供酒店信息、价格、房型、预订等相关业务接口,合作伙伴可以通过这些接口获取携程平台上的酒店数据,并进行自主展示和预订。图5 酒店城市数据预览。

ETLCloud的博客 504

阿里云redis CRDT产品支持说明

CRDT支持概述 CRDT天然支持redis的几种数据结构,下表给出一个简单映射: redis数据结构 CRDT数据结构 string(int或double类型编码) counter string register set set 基本kv set + register hash set + register zset se...

weixin_34390996的博客 522

20张最全的架构师技术栈图谱

小编根据经验收集以下20张关于架构师应该了解和掌握的技能图谱,希望这份技术知识图谱能够帮助到每一位奋斗在技术路上的小伙伴。架构师图谱微服务架构秘籍互联网大流量的方法安全秘籍阿里巴巴常用小...

weixin_45727359的博客 2142
上一篇: 干货 | 关于SwiftUI,看这一篇就够了
下一篇: 早鸟票抢购 | 2019携程技术峰会,11月9日上海
携程技术
博客等级 码龄10年 3716粉丝 324原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值