带有数据的rails中的Postgresql复制

我目前正在使用Ruby on Rails设置主从应用程序。 我打算使用数据结构或章鱼gem来处理读/写连接。

这是我第一次设置主从DB。 我对可用于实现postgresql复制的各种开源工具感到困惑,例如pgpool II,pgcluster,Bucardo和Hot Standby / Streaming Replication(内置于postgresql 9.1中的特性)

我的要求是

  • 容错(高可用性和故障切换时不会丢失数据)
  • 负载均衡
  • 提前致谢

    注意:我已经通过了有关postgresql复制的stackoverflow帖子,但它们很老,并没有帮助推断我应该使用哪个工具。


    在你的情况下,流式复制是开始的地方。 它不是非常灵活,但只要您不需要在主要版本之间进行复制,它就可以执行数据库读取所需的操作。

    数据库复制101

    数据库复制是一种确保保存到特定服务器的数据存储在其他许多服务器中的方法。 这通常是为了更好地利用更多有限的网络连接,确保容错能力(因此基本上存在热备份),确保只读查询可以分布在大量数据库等上。这一切都必须完成而不会牺牲ACID的基本保证。

    有多种不同的重叠方式来对复制解决方案进行分类。 这些包括:

  • 页面或文件级别与行级别与语句级别

  • 同步与异步

  • 主从与多主

  • 总的来说,理解复制和解决方案之间的权衡需要对数据库机制和ACID保证有较强的理解。 我会假设你对存储机制,确定性操作和非确定性操作等都比较熟悉。

    什么是复制? 文件更改(物理)与行更改(逻辑)与语句

    最简单的方法是将块更改复制到文件中,例如存储在PostgreSQL的预写日志中。 这复制了页面级别的更改,它需要相同的文件格式。 这意味着您无法跨主要版本,CPU架构或操作系统进行复制。 例如,任何可能影响元组对齐的东西都会导致复制失败,或者更糟糕的是会破坏从属数据库。 这是流式复制使用的方法。 设置起来很简单,它总是复制数据库集群中的所有内容。

    此外,这种方法意味着您可以轻松保证主数据库和从属数据库在文件级别上是相同的。 由于PostgreSQL WAL是集群全局的这一事实,这种方法不可能复制任何短于整个数据库集群的任何事情。

    作为如何工作的描述,假设我:

    UPDATE my_table SET rand_value = random() WHERE id > 10000;
    

    在这种情况下,这会更改一堆数据页面,并将文件操作复制到副本。 主站和从站之间的文件保持一致。

    另一种方法,Slony,Bucardo和其他人采用的方法是以逻辑方式复制行。 在这种方法中,更改的行会被标记并记录,并将更改发送到副本。 副本重新从主数据库运行行操作。 因为这些附加工具不会复制文件操作,而是逻辑数据库操作,所以它们可以跨CPU架构,操作系统等进行复制。它们通常设计为可以复制数据库中的一些但不是全部表,考虑到很多灵活性。 另一方面,这导致了很多潜在的错误。 “糟糕,表格没有被复制”是一个真正的问题。

    在这种情况下,当我运行上面的update语句时,会触发一个触发器,捕获插入和删除的实际行,并记录,复制和重新运行这些行操作。 因为这发生在rand()运行之后,所以数据库在逻辑上是相同的,但不一定是物理上相同的。

    最后的方法是语句复制。 在这种情况下,我们复制语句并重新运行副本上的语句。 PgPool的一些配置将执行此操作。 在这种情况下,如果运行任何非确定性函数,则无法确保数据库在逻辑上等同于其副本。 在上面的声明中,声明本身将在每个副本上运行,从而确保相关列中的不同伪随机数。

    同步与异步

    这一区别对于了解故障转移保证很重要。 在异步复制系统中,更新排队并尽可能传输到副本并在其中重新运行。 在同步复制系统中,接受写入的数据库将不会返回成功的提交,直到至少一定数量的副本数据库报告成功提交为止。

    异步复制通常更健壮并且产生比同步复制更好的可用性。 这是因为同步复制引入了额外的故障点。 如果您有一个主控和一个从控,那么如果任一个系统停机,您的数据库至少在写操作时不可用。

    尽管如此,权衡是因为同步复制提供了一种保证,即承诺的数据事实上可在复制副本上获得,如果主人在提交后立即遭受灾难性硬件故障。 这是一个非常低的概率事件,但在某些情况下,重要的是您知道数据仍然可用。 总而言之,这提供了异步复制中不存在的额外的持久性保证。

    多主与主从

    大多数复制系统都是主从。 在这种情况下,所有写操作都从一个节点开始并被复制到其他节点。 写入只能从一个节点开始。 他们可能不会从其他节点开始。 这使得复制变得简单直接,因为我们知道从属表示主节点的过去状态。

    多主复制允许写入发生到多个节点。 在异步复制系统中,这导致了冲突解决问题。 这些问题实际上比添加DDL语句时大多数人认为的更糟糕。 假设两个不同的用户在两个不同的主人上运行上述更新语句。 我们现在有一组必须复制的记录,但它们会发生冲突。

    多主复制通常要求人们仔细考虑通过这个冲突解决过程。 它从来不是一个只是开箱即用的过程。 通常你会编写自己的冲突解决程序。 出于这个原因,我通常建议避免多主复制,除非你真的需要它。

    链接地址: http://www.djcxy.com/p/77379.html

    上一篇: Postgresql replication in rails with data

    下一篇: Which PostgreSQL replication solution to use for my specific scenario