构建数据库以进行扩展就绪的最佳实践

时间:2011-12-13 10:06:21

标签: database postgresql optimization scaling

我知道这是一个非常通用和主观的问题,如果它不符合StackOverflow网络礼节,请随意投票关闭它...但对我来说,值得尝试;)

我从来没有建立过高流量的应用程序,所以我不知道(除了网上的一些阅读)关于扩展实践。

如何设计一个数据库,当需要扩展时,我不必重构数据库结构或应用程序代码?

我知道开发(和优化)应该逐步进行,在发生时优化瓶颈,并且当你不知道你将拥有多少用户时几乎不可能设计完美的结构他们使用数据库(例如读/写比率),我只是在寻找一个良好的基础来开始。

使用partitioningsharding几乎准备好扩展结构的最佳做法是什么?必须绝对避免hacks

修改有关我的应用程序的一些细节:

  1. 应用程序将作为多站点行为运行
  2. 我将为每个应用程序版本(db_0_0_1,db_0_0_2等等)提供数据库*)
  3. 每个“网站”都有一个数据库内的模式*和一个只能访问自己模式的角色
  4. 应用程序代码主要是PHP和Python中的一些东西(守护进程和维护东西)
  5. Web服务器可能是Nginx和lighttpd或node.js,作为长轮询任务的支持(例如聊天)
  6. 缓存将使用memcached(加上apc用于与php代码严格相关的内容,因为它可以在php外部使用)

1 个答案:

答案 0 :(得分:3)

这个问题非常通用,但这里有一些提示:

  • 不要在应用程序代码中使用任何会话变量(pg_backend_pid(),inet_client_addr())或每会话控制(SET ROLE,SET SESSION)。

  • 不要在应用程序代码中使用显式事务控制(BEGIN / COMMIT / SET TRANSACTION)。所有这些逻辑都应包含在UDFs中。这样可以启用无状态语句模式池,从而实现最快的DB池。 (有关详细信息,请参阅pgbouncer docspg wiki

  • 在UDF定义良好的DB API中封装所有App< - > Db通信 - 这将允许您使用PL / Proxy。如果对所有SELECT执行此操作太困难,请至少对所有数据写入执行此操作(INSERT / UPDATE / DELETE)。示例:代替INSERT INTO users(name) VALUES('Joe'),您需要SELECT create_user('Joe')

  • 检查您的数据库架构 - 是否可以轻松分离属于给定用户的所有数据? (很可能这将是分区键)。剩下的就是常见的共享数据,需要将其复制到所有节点。

  • 在需要之前考虑缓存。什么是缓存关键?什么是缓存超时?你会用memcached吗?