Database 将数据库构造为可伸缩的最佳实践

Database 将数据库构造为可伸缩的最佳实践,database,postgresql,optimization,scaling,Database,Postgresql,Optimization,Scaling,我知道这是一个非常普遍和主观的问题,所以如果它不符合StackOverflow网络礼仪,请随意投票关闭它。。但对我来说,这值得一试;) 从现在起,我从来没有构建过高流量的应用程序,所以我不知道(除了一些网络阅读之外)扩展实践 如何设计一个在需要扩展时不必重构数据库结构或应用程序代码的数据库? 我知道开发(和优化)应该循序渐进,在瓶颈发生时进行优化,当你不知道有多少用户以及他们将如何使用数据库(例如读/写比率)时,几乎不可能设计出完美的结构,我只是在寻找一个良好的基础 使结构几乎可以通过分区和分片

我知道这是一个非常普遍和主观的问题,所以如果它不符合StackOverflow网络礼仪,请随意投票关闭它。。但对我来说,这值得一试;)

从现在起,我从来没有构建过高流量的应用程序,所以我不知道(除了一些网络阅读之外)扩展实践

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

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

使结构几乎可以通过
分区
分片
进行缩放的最佳实践是什么?必须绝对避免的
黑客行为是什么

编辑有关我的应用程序的一些详细信息:

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

  • 这个问题其实很普通,但这里有一些提示:

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

    • 不要在应用程序代码中使用显式事务控制(开始/提交/设置事务)。所有这些逻辑都应该包含在内。这将启用无状态的语句模式池,从而实现尽可能快的数据库池。(有关更多信息,请参见和)

    • 将所有AppDb通信封装在UDF的定义良好的DB API中-这将允许您使用PL/Proxy。如果对所有选择执行此操作太难,请至少对所有数据写入(插入/更新/删除)执行此操作。示例:您需要
      选择create\u user('Joe')
      ,而不是
      插入用户(名称)值('Joe')

    • 检查您的数据库模式-是否容易分离属于给定用户的所有数据?(这很可能是分区键)。剩下的就是需要复制到所有节点的公共共享数据

    • 在需要缓存之前考虑缓存。缓存密钥将是什么?什么是缓存超时?你会使用memcached吗


    我更新了我的问题,只提供了一些关于我的应用程序的细节-你能再解释一下事务控制吗?为什么我不应该在我的应用程序代码中使用它?我已经更新了我的答案,但我觉得我不是这方面的真正专家,所以我们必须等待有人提出更好的bag'o'提示:0)也许吧?我欢迎你提前思考在你的设计上,而不仅仅是潜入并期待最好的。然而,我能给你的最好的建议是,当你第一次认为你需要切分或分区时:不要!仔细看看你们的数据库利用率模式,你们可能会发现这是对数据库的一种糟糕的使用,而不是需要“扩展”。很多时候,我看到人们试图通过切分来扩展糟糕的代码。它源于“用硬件解决问题”的想法。现在他们有更多的硬件需要维护,还有一个共享的基础设施,剩下的代码仍然很糟糕。@MatthewWood我已经做了一个项目构建,带有“最好的祝愿”,nit本来应该是一个“个人”项目,但后来发展成了中小型项目。。数据库(和代码)是维护的噩梦;)我不想犯同样的错误两次;)我同意你的观点,大多数优化应该首先在代码中进行,硬件扩展是最后一次尝试