前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >liquibase和flyway中分布式锁实现的区别?

liquibase和flyway中分布式锁实现的区别?

作者头像
Bruce Li
发布2019-08-21 18:06:34
1.8K0
发布2019-08-21 18:06:34
举报

大家可能都知道,锁的存在本质上是为了解决共享资源互斥访问的问题,为了解决这个问题,在单机系统中(一个进程),很多开发语言都提供了锁的特性,比如说java的synchoronized、lock等;在分布式系统中(多个进程),则需要实现分布式锁,因为语言层面的锁特性不足以解决问题。

关于分布式锁的概念、特性以及实现方式,网上有很多相关的文章,感兴趣的童鞋可以自行搜索。

简单讲,分布式锁也需要满足一般开发语言提供的锁的一些基本特性:

  • 互斥性:多个线程(可能位于不同的进程上)访问共享资源时,同时只能有一个线程访问。
  • 阻塞性:一个线程访问共享资源时,其他线程应该被阻塞执行。
  • 容错性:有机制防止死锁的发生,如果一个线程得到了锁,但是由于不正常退出(比如:宕机)导致锁没有显示释放,在这种情况下,需要有机制把这个锁释放掉,防止死锁发生。

现在常见的分布式锁的实现方案有:

  • 基于数据库实现分布式锁
  • 基于缓存(redis,memcached etc.)实现分布式锁
  • 基于Zookeeper实现分布式锁
  • ...

上面分享了一些关于分布式锁的理论知识,接下来从liquibase和flyway两个library来解析它们实现分布式锁的区别。

有同学可能知道,liquibase和flyway是数据库表结构改变的管理工具,这类工具的目的是使对数据库表结构的改变做到自动化,以防止人工对数据库表结构的改动带来的风险。两个工具的基本原理都类似,即是对数据库表结构的每一次改动维护成一条changeset(changeset可以是创建一个表,也可以是增加一个字段等),当应用程序启动时,会依次执行维护的changeset,一旦changeset被执行过,就不会被再执行,具体如何使用可以查看:

  • liquibase:https://www.liquibase.org/index.html
  • flyway:https://flywaydb.org/

目前,这两个工具在很多项目中都有应用。

之前在项目(微服务架构)中,遇到过一个liquibase的问题:一个service用liquibase管理数据库change,有时候service在启动阶段突然crash,再次启动,一直启动不起来,控制台一直看到如下日志:

代码语言:javascript
复制
INFO … Liquibase: Waiting for changelog lock....
INFO … Liquibase: Waiting for changelog lock....
INFO … Liquibase: Waiting for changelog lock....

在另外一个场景,有时候也发现过类似的问题,一个service有两个instance,在第一个instance启动阶段,由于未知原因突然crash,这时候第二个instance再也启动不起来,控制台同样看到和上面一样的日志:

代码语言:javascript
复制
INFO … Liquibase: Waiting for changelog lock....
INFO … Liquibase: Waiting for changelog lock....
INFO … Liquibase: Waiting for changelog lock....

而同样的,有的service使用的flyway,却没有遇到过这样的问题。这是为什么呢?

当然,在正常情况下,第一个service启动没问题,另外一个service就会成功启动起来。

其实,上面这个场景是典型的一个分布式锁应用的场景:service的两个instance需要互斥访问数据库以执行changeset,第一个instance执行过程中,第二个instance需要阻塞等待;第一个instance执行完了,会自动释放锁,接着第二个instance继续执行。

由于这两个library本身就是数据库相关的工具,天然就要依赖数据库,所以采用的分布式锁的实现方案就是基于数据库实现的方案。通常,基于数据库实现分布式锁有两种方式(参考https://blog.csdn.net/dingjianmin/article/details/82763871):

  1. 基于数据库表
  2. 基于数据库排他锁

两个library分别采用了这两种方式,Liquibase采用的是第一种-基于数据库表,Flyway采用的是第二种-基于数据库排他锁。

Liquibase维护了一张databasechangeloglock表来实现分布式锁。

Flyway则利用的是数据库的排他锁,如下图源码所示。(参考http://dbabullet.com/index.php/2018/03/29/best-practices-using-flyway-for-database-migrations/)

采用第一种基于数据库表的实现方式,一个关键的问题就是,如何防止一个线程解锁失败,导致锁记录一直在数据库中,其他线程无法再获得到锁?而这个问题也就是上面项目中遇到的liquibase的问题,一个service instance突然crash导致解锁失败,其他线程无法再获得到锁。

对于这个问题,liquibase官网只给出了一个workaround去清理脏锁,没有具体的计划fix这个问题。

而由于flyway采取的是第二种基于数据库排他锁的方式,则不会有这个问题。因为基于数据库的排他锁,如果service突然crash,service跟数据库的连接也就会断掉,加在表上的排他锁就会自动释放,进而接下来其他线程可以继续获得锁。

最后,针对分布式锁各种方案的解释,网上有很多写得挺好的文章,下面列出一些仅供参考:

References

  • https://blog.csdn.net/dingjianmin/article/details/82763871
  • https://blog.csdn.net/u013871100/article/details/83718047
  • http://www.liquibase.org/documentation/databasechangeloglock_table.html
  • http://dbabullet.com/index.php/2018/03/29/best-practices-using-flyway-for-database-migrations/

欢迎关注公众号与作者交流

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 天马行空布鲁斯 微信公众号,前往查看

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

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档