Postgres复制:我应该使用内置机制还是让中间件控制它?

时间:2012-07-15 14:47:53

标签: java postgresql replication

对于我的宠物项目(已超出预期),我需要添加某种形式的负载平衡和故障安全性。该项目使用三层:

  1. 前端(客户访问)
  2. 中间件(提供前端和后端之间的通信)
  3. 后端(业务逻辑,数据存储)
  4. 中间件是Java servlet,后端是PostgreSQL。每个客户都有一个数据库,因此有些DB会在整个时间内来来往往。后端非常简单,因为新数据每24小时导入一次,其余时间基本上是只读的。

    为了使整个系统更具弹性(服务器故障,加载峰值等),我现在想将后端复制到其他服务器上。然后,中间件可以将请求均匀地分发给所有正在运行的后端。

    现在问题是如何处理复制:

    1. 让中间件完成所有工作(进行数据库转储,将转储推送到其他后端服务器并恢复)
    2. 使用Postgres的内置机制(Slony,Streaming Repliation等)
    3. 两种方式都有其优点和缺点,并且感觉不完全正确。我的主要想法是:

      • 使用中间件可以提供更好的控制,我可以更轻松地确定当前存在的客户并仅复制这些数据库。将新的后端服务器添加到群集会更容易。我可以按需进行复制,即。何时导入此客户的新数据。正确处理pg_dump和pg_restore
      • 涉及相当多的开发工作
      • 使用内置机制可以节省一些工作,并且可能会更好,更可靠。我需要在后端服务器(SSH,VPN)之间提供一些通信通道。

      那么,这里更好的方法是什么?我倾向于喜欢中间件选项,但这可能只是我对Postgres的非常有限的体验。

      奖金问题:如果Postgres复制是更好的选择,哪种机制(现在Postgres 9中有相当多的机制)对我的场景最好?

3 个答案:

答案 0 :(得分:1)

简短的回答,建立在现有解决方案之上。复制很难,许多聪明人已经完成了大部分工作。 Slony,Londiste,Streaming Replication都为您提供了不同的功能,但这些功能都有一个共同之处:它们确实有效。至于你选择哪个,这取决于你想要实现的目标。

流复制将为您提供多个只读节点,这些节点仅略微位于主节点之后(通常不会显示)。它将消除应用模式更改的管理开销,它是二进制复制。但是,它是全部或全部复制(在集群级别进行复制)。设置并不是特别困难,只要您具有对所有服务器的root访问权限。

Londiste / Slony将让您更好地控制复制的内容,让您可以控制到桌面级别。这样可以轻松添加仅执行单个任务的节点 - 即一个业务领域 - 这对您来说可能有用也可能没用。安装涉及更多,模式迁移更复杂。使用Londiste,您可以获得PGQ,因此您现在在数据库中有一个消息队列,这可能会对您的其他业务部门有用或可能没用。

我刚刚设置了二进制流复制(一个热备用节点),因为我们的生产数据库最近有一个小的打嗝,所以这就是故障转移的原因。我对它的工作原理印象深刻,以及它是如何更新的,我们还在考虑对此节点进行只读查询的负载平衡。我对Londiste有过简要的经验并发现它有很好的文档记录,但我通常希望整个集群复制,所以热备用对我来说最有意义。

除了浪费时间/制造错误/为自己提供比你需要的工作更多的工作之外,我没有看到你自己在复制中获得什么。

答案 1 :(得分:0)

我同意ocharles的意见,认为在这里重新发明轮子是没有意义的。但是,如果pg_dump / pg_restore可以为你做这个非常好的设置。完全转储/恢复通常不适用于复制的原因是:

  1. 数据库太大 - 完全转储/恢复需要的时间太长。

  2. 数据库过于活跃 - 您需要保持副本最新。

  3. 如果这些不是您的问题,那么您的复制过程可能只是:

    对于每个数据库......

    1. 将“即将在时间T进行备份”插入某些记录表

    2. pg_dump数据库

    3. 将备份复制到一个或多个从属

    4. pg_restore的

    5. 检查我们从上面插入的时间戳是否存在于奴隶

    6. 这很简单,可维护,并为您提供了一个很好的奖励 - 每个活动数据库的每日,可存档,自包含的备份。

      当然,如果您的数据库变得太大,或者需要每天更新一次,那么 将不适合您。

答案 2 :(得分:0)

通过OP回答后续问题 - 设置/配置Londiste非常简单。只需几个简单的步骤,然后您可以在master上添加任意表进行复制,并在目标数据库上实现它们(可以使用级联复制)。在skytools包中的doc文件夹中有多个how-to,用于描述不同的场景。