我有一个非常繁重的java webapp,它服务于数千个请求/秒,它使用一个主Postgresql数据库,它使用流(异步)复制将自身复制到一个辅助(只读)数据库。
因此,我使用URL将请求从主要服务器分离为辅助服务器(只读服务器),以避免对错误主数据库进行只读调用,因为复制时间很短。
注意:我使用一个sessionFactory和一个由spring提供的RoutingDataSource,它根据一个键查找db。我对多租户感兴趣,因为我正在使用支持它的hibernate 4.3.4。
我有两个问题:
我知道我可能在这里得不到完美的答案,因为这确实很广泛,但我只是想要你的意见。
我的团队中有些人:
请关注。提前谢谢。
答案 0 :(得分:6)
你应该:
对于batch processing,您肯定需要写入最多的事务,但一般来说OLTP和特别是Hibernate不是最适合OLAP的。如果您仍然决定将Hibernate用于您的石英作业,请确保enable JDBC batching并且您应该设置这些Hibernate属性:
<property name="hibernate.order_updates" value="true"/>
<property name="hibernate.order_inserts" value="true"/>
<property name="hibernate.jdbc.batch_versioned_data" value="true"/>
<property name="hibernate.jdbc.fetch_size" value="25"/>
<property name="hibernate.jdbc.batch_size" value="25"/>
对于批处理,您可以使用使用不同连接池的单独数据源(并且因为您已经说过您拥有与您已有的不同的JVM)。只需确保所有连接池的总连接大小小于PostgreSQL配置的连接数。
因此批处理器使用连接到master的单独HikariCPDataSource。每个批处理作业必须使用专用事务,因此请确保使用合理的批处理大小。您希望保持锁定并尽快完成交易。如果批处理器使用并发处理工作程序,请确保关联的连接池大小等于工作者数量,因此他们不会等待其他人释放连接。
答案 1 :(得分:1)
您说您的应用程序URL只有10%只读,因此其他90%至少有某种形式的数据库写入。
10%阅读
您可以考虑使用可能会提高数据库读取性能的CQRS design。它当然可以从辅助数据库中读取,并且可以通过专门为读/视图层设计查询和域模型来提高效率。
您尚未说明10%的请求是否昂贵(例如运行报告)
如果您要遵循CQRS设计,我宁愿使用单独的sessionFactory,因为正在加载/缓存的对象很可能与正在编写的对象不同。
90%写作
至于其他90%的用户,在一些写入逻辑期间,您不希望从辅助数据库读取(在写入主数据库时),因为您不希望涉及可能过时的数据。
其中一些读取可能会查找“静态”数据。如果Hibernate的缓存没有减少读取的数据库命中,我会考虑像Memcached或Redis这样的内存缓存来处理这种类型的数据。 10%-Read和90%-write进程都可以使用相同的缓存。
对于非静态读取(即读取您最近编写的数据),如果Hibernate的大小合适,Hibernate应该将数据保存在其对象缓存中。你能确定你的缓存命中/未命中性能吗?
<强> QUARTZ 强>
如果您确定预定作业不会影响与另一个作业相同的数据集,则可以针对不同的数据库运行它们,但如果有疑问,则始终对一个(主)服务器执行批量更新并复制更改出。在逻辑上更正确,而不是引入复制问题。
DB PARTITIONING
如果您每秒1000个请求正在编写大量数据,请查看partitioning您的数据库。你可能会发现你有成长表。分区是在不归档数据的情况下解决此问题的一种方法。
有时您只需要很少或不需要更改应用程序代码。
存档显然是另一种选择
免责声明:任何类似的问题始终都是针对特定应用的。始终尽量使您的架构尽可能简单。
答案 2 :(得分:0)
如果我正确理解,90%的对您的webapp的HTTP请求至少涉及一次写入,并且必须在master数据库上运行。您可以将只读事务定向到副本数据库,但改进只会影响全局数据库操作的10%,甚至那些只读操作也会影响数据库。
这里的通用架构是使用一个好的数据库缓存(Infinispan或Ehcache)。如果你可以提供足够大的缓存,你可以希望数据库读取的很大一部分只访问缓存并成为仅内存操作,或者是只读事务的一部分。高速缓存调整是一项微妙的操作,但IMHO是实现高性能增益所必需的。即使在这种情况下配置有点困难,这些缓存甚至允许分布式前端(如果你想使用Ehcache,你可能需要寻找Terracotta集群。)
目前,数据库复制主要用于保护数据,并且只有当信息系统的高部分只读取数据时才会用作并发性改进机制 - 而且它不是您所描述的。