从数据库实现实时查询/更新(AKA连续查询处理)

时间:2013-09-27 20:52:00

标签: sql database performance oracle scalability

我们有一个关系数据库表来累积客户的订单。订单具有不同的类型和参数以及它们的生命周期(例如,新的,修改,更新,取消等)。

要求:

  1. 一天内有大约300万份订单进入。
  2. 峰值速率是每秒400个新订单 - 它的插入率很高。
  3. 不断增长的数据库目前有1亿个订单。当然,他们可以被查询和汇总。
  4. 全球数以百计的消费应用需要:
    • 通过数据库中的过滤器获取日期/时间范围内的一组订单。
    • 通过过滤器订阅/持续收听订单的传入更新。 (过滤器是订单应满足的一组条件,因为每个应用程序都对特定数据集感兴趣)。
  5. 我们需要一个满足上述所有要求的服务器端应用程序。

    问题:

    1. 我们无法实现No.1的实时要求(每个订单的<100毫秒延迟)。由于频繁的表插入/更新以及RDBMS中可更改的select语句,查询聚合等,SQL查询非常慢。
    2. 目前我们还没有灵活的订阅过滤器。
    3. 目前的解决方案无法扩展。 RDBMS是主要的瓶颈。
    4. 我将很高兴听到建筑和技术理念。 谢谢。

2 个答案:

答案 0 :(得分:3)

分布式缓存

Hazelcast是Oracle Coherence的分布式缓存实现和免费开源替代方案,它还支持Write-behind和Continuous Query机制,这些机制可以解决您的三个问题。

  1. 使用write-behind通过缓存进行异步数据库写入。
  2. 使用Continuous Queries接收每个缓存放置操作的实时更新。
  3. 分发Hazelcast,启动群集非常容易。使用write-behind,您的可伸缩性受到hazelcast节点数量和可用内存量的限制。
  4. 信息

    消息传递中间件是另一种可用于解决问题的选项。

    1. 利用异步队列/主题卸载数据库。队列/主题将以灵活的方式进行逻辑分区,以便能够调整数据库上的负载。这将需要在消息传递和数据库之间开发一个单独的层。
    2. 同样,使用主题订阅传入的订单以创建连续查询的效果(消耗订单并将其持久保存到数据库的层将负责发送更新)。
    3. 许多消息代理实现还支持群集/分发以实现额外的并行化和可伸缩性(例如,HornetQ)。
    4. 请注意,通过消息传递,您可以同时获得高可用性,可靠性和可伸缩性。

      数据库级

      假设您使用Oracle作为数据库,至少有以下问题1-3:

      1. 按地区/日期范围/客户名称/其他类别对表进行分区 - 无论适合您的特定情况 - 都会为您提供扩展读/写的空间。如果你有很多可用于Oracle的CPU核心,那么适当的分区可以大大提高大数据集的查询性能,从而利用并行化水平(在一个项目中,我们实现了从5小时到10分钟的处理大型数据集的改进)。 / LI>
      2. INSERT触发器与Oracle Advanced Queuing结合使用可用于实现连续查询(尽管外部消息传递代理在某些情况下可能更好)。
      3. 见#1。
      4. 事实上,您可以考虑上述方法的组合,以实现特定案例的最佳性能和可扩展性。

        我没有考虑迁移到NoSQL数据存储区,因为IMO,NoSQL解决方案不适合数据一致性至关重要的应用程序,我认为这是你的情况。

答案 1 :(得分:2)

在这种情况下,CQRS设计模式可能是合适的 see here, Martin Fowler's article

想法是分离选择和插入/更新命令