首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  程序员

微服务+redis 事务解决方案

  •  
  •   Breadykid · 42 天前 · 1644 次点击
    这是一个创建于 42 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近要实现的需求: BI 的 etl 模块,就是 2 个数据库同步数据,A 服务 A 库读数据,B 服务 B 库存数据,这个过程会很长,期间发生异常,或者人为手动取消这个过程,B 库里存的数据就要全部回滚。 其中数据库不限,目前支持的有 mysql,Postgres,oracle,sqlserver, 这个功能类似用 navicat 来同步两个数据库里表的操作

    流程图如下,想问我要带上 redis 事务,和用 feign 的 hystrix 的回退模式,怎么做较好? 目前所有的 2 个微服务间的数据异常回滚操作都是用 try-catch,catch 里调用失败要执行的操作在代替事务,都是手动在 Connection.commit,Connection.rollback,我觉得这样不太对,但又不知道要怎么写,真的脑壳痛。。。 https://www.processon.com/view/link/5d4262d5e4b0b3e4dcdaba77

    23 回复  |  直到 2019-08-09 09:55:14 +08:00
        1
    Breadykid   42 天前
    不是伸手党啊各位,对这块不会,不知道怎么实现,目前的实现经不起压测
        2
    jybox   41 天前
    两阶段提交
        3
    Breadykid   41 天前
    @jybox 不能引入 seata 之类的框架,手动实现二阶段怎么搞哇?
        4
    zhaorunze   41 天前
    领导上次技术分享说过思路,就是利用 redis,但是经不起细细推敲。seata 有一个控制中心,利用 redis 如果没有控制中心,会多很多复杂的操作。
        5
    snappyone   41 天前
    这个图看的晕啊
        6
    vmskipper   41 天前
    数据同步 库 A 10 亿 导入库 B 如果第 9 亿条失败 要回滚。。。 数据同步开源工具那么多
        7
    kkkkkrua   41 天前
    为什么我感觉复杂化了,是我理解错了吗?
    当 B 库插入发生异常时候,清空掉所有数据不就可以了吗,为啥要分布式事务
    如果是在已有基础上做增量插入的话,把当前 B 库的数据新增表,然后插入,再用数据库事务迁移过去。
        8
    rayu   41 天前 via Android
    之前面试被问住了,反问之后说用 kafka
        9
    liprais   41 天前 via iPhone
    往 b 里面写的时候批量导入开事务就行了
        10
    agostop   41 天前
    大概想了一下,弄个唯一的事务 ID 作为 key,每次提交 B 库的时候使用数据库事务保证完整性;
    写入成功把这个 ID 提交给中间件,让中间件去同步;
    中间件处理后,写入 A 数据库时依旧靠数据库事务,如果写入 A 库失败,根据事务 ID 删除 B 库存储条目
        11
    hantsy   41 天前
    对于微服务,

    1. 天下没有免费的午餐。微服务开发难度很大,运维会面临空前的挑战。业务领域没弄清的话,或者你的项目没经历 DDD 建模, DevOps 空白或者不到位,没有实现自动化部署,不要盲目上微服务。马大叔文章也是建议从 Monolithic 开始,微服务是个演进的过程。
    2. 跨服务的事务(不再是传统事务,传统事务处理不适合了。传统事务时间都很短。而微服务牵涉到多个服务,可能跨度几天,比如旅游订票流程,先预付了机票酒店,结果等了两天没出机票,对账后,全部一一退回),实现数据最终一致性的难度很大。可行的方法,1. 基于消息模型可以自己实现,相关的服务监听相应的事件(作用 RabbitMQ/kafka 等,比如,place order, cancel order, 等),实现上比较自由 , 2 也可以使用一些现有的工具架构定义 Saga 模型 ,在一个很长的运行单元中,每一步操作提供一个 Compensation 任务(回退操作),这种更易管理,更健壮。https://medium.com/@tomasz_96685/saga-pattern-and-microservices-architecture-d4b46071afcf
        12
    mineqiqi   41 天前
    啥意思,只有 b 库的数据全部落盘才会同步到 a 库,还是边落库边同步,然后如果数据落盘异常全部数据回滚? 不论是哪种场景 这么多的数据只要有异常就全部回滚这种操作都是不合理的,一开始设计的时候就有问题
        13
    jk1030   41 天前
    kafka ack
        14
    agostop   41 天前
    不全部回滚会造成脏数据的吧
        15
    cyhulk   41 天前
    这个问题感觉完全不是分布式事务的范畴,B 落库的过程非常长,甚至可以人为干预关闭,如果真的是分布式事务,你这个请求的占用时间太长了,完全不如说你提供回退的接口或者通过消息队列自动触发,你自己做好回退的消息
        16
    gaius   41 天前
    不是同步调 B 的话,A 库保存消息和一个状态就好,用定时任务或者队列消费做下事务控制完成后再去做确认。人工取消不是太懂,也可以 B 写一个 cancel 方法吧。 csv 文件放哪就好,数据库存路径。
        17
    Breadykid   40 天前
    @vmskipper 就是不给用其他工具啊
        18
    Breadykid   40 天前
    @mineqiqi 就是全部落盘才会同步到 a 库的需求呢
        19
    Breadykid   40 天前
    @kkkkkrua 意思是建临时表吗
        20
    Breadykid   40 天前
    @liprais 数据库事务还是别的?可以具体点嘛?
        21
    Breadykid   40 天前
    @mineqiqi 产品看到别家做了这个功能,就要我们也实现。。。
        22
    Breadykid   40 天前
    @cyhulk 所以还是我目前的解决方案嘛
        23
    Breadykid   40 天前
    @agostop 中间件有具体推荐嘛?搭建成本(机器成本)高的就算了,领导肯定不同意
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4008 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 30ms · UTC 09:12 · PVG 17:12 · LAX 02:12 · JFK 05:12
    ♥ Do have faith in what you're doing.