设置数据库分片 - 没有跨数据库查询

时间:2011-08-09 03:44:48

标签: mysql spring scalability sharding mysql-proxy

我正在开发一个Web应用程序,在这个应用程序中,对于每个客户端(一个小型​​大型组织),他们不会(也不应该)能够查询到其他客户端的记录。

将数据保存在单个数据库中很容易,并且更新和维护简单(直到我遇到可伸缩性问题)。但我现在想要面向未来的应用程序。如果每个客户的数据都包含在隔离的数据库中,那么每个客户端都会有更好的性能并且应该更好地扩展。我不确定它是否等同于数据库“分片”,因为我没有在多个数据库之间划分单个模式。我基本上会在每个数据库中复制一个模式(就像在CD上发送软件的那一天 - 每个都有自己的数据库)。

我已经读了一下这个,所以我对一般概念有所了解。但是,我脑子里有很多问题。我不确定这个过程有多透明。或者,如果我想在推出更改时更新数百个模式,我将遇到维护噩梦。

真的,我只是在寻找一个简单的“完整”示例(希望使用spring / java)。

  1. 我想我可以让一个应用程序服务器以一个数据源开头,假设一个mysql实例有一个表将userid映射到数据库。

    • 用户ID
    • 数据库/碎片-ID

    对于每个请求(查询),忽略数据库缓存,是否必须查找用户的分片ID?或者这是最初每次会话可以做一次并直接与目标数据库对话的东西吗? (正如你可能能说我对服务器端的东西不强)。

  2. 有人可以高度概述一下如何在Spring中连接它吗?目前,我的架构非常简单。我有简单的Spring组件DAO使用jdbctemplate。注入DAO的数据源(datasource在applicationContext.xml上配置)。 DAO已自动连接到我的服务类中。很标准的东西。

  3. 假设我上一步工作,现在我必须更改架构。是否有管理工具可用于应用模式更改一次并将其传播到其他100个数据库?

  4. 我正在使用MySQL。我相信“MySQL代理”可能能解决问题1和2.有没有人有这方面的经验?我想它无法处理架构更新,因此我可能不得不推出自己的解决方案。

    谢谢!

5 个答案:

答案 0 :(得分:1)

我在我的公司使用spring和sharding这个想法是

  1. 您将实现一个基本上是连接池池的ShardDataSourceManager,您可以通过分片ID查找数据源。
  2. 您将定义自己的Transactional注释并使用它注释方法
  3. 你需要在dao层写一个拦截器来读取方法和一些上下文信息的注释。从上下文信息中,您可以查找分片ID和查找 数据源并注入本地线程。
  4. dao层在查找数据源时会查找本地线程以构造一个jdbc模板并对其执行查询。

答案 1 :(得分:0)

我无法与Spring交谈,因为我不使用它。

如果是我,在我的Java EE帽子上,我只需使用JNDI数据源,为每个客户端创建一个,并通过客户端名称或用于区分客户端的任何标识符查找。

现在,我确信可以用Spring完成,我只是无法告诉你如何。

常见的数据库连接池实现如何处理具有多个连接的“100个数据库”,这也是一个不同的问题(想到几百个开放连接套接字的愿景)。我也无法与之交谈,也没有这样做。

但在那之后,由于每个池指向一个单独的数据库,所以基本上你都完成了。每个池都可以拥有自己的配置,因此您可以将DB移动到不同的主机等。

这将是我第一次解决问题,直到它在测试中失败,但我猜测失败点将是数据库池实现或与之相关。其他一切都是通用的DB服务器和Java。

答案 2 :(得分:0)

我不太了解春天,所以不能谈论它。 但是对于数据库分片,我建议你看一下高可扩展性

这篇文章

New Relic Architecture - Collecting 20+ Billion Metrics a Day

它讨论了很好的分片策略以及它在负载变化时的帮助。另请查看评论部分,其中提供了有关分片的更多详细信息。

答案 3 :(得分:0)

您可以使用DDAL来实现访问DAL中的不同数据库,并且它不依赖于spring的数据源和事务管理。还有一个演示项目,展示如何使用它:https://github.com/hellojavaer/ddal-demos。你可以尝试一下。

答案 4 :(得分:-1)

这是一种分片/多租户情况。您将面临维护噩梦,并且需要编写分配代码。您可以使用第三方 - 您可以尝试ScaleBase(披露:我在那里工作),他们按照您的描述完全按照您的应用程序进行操作。