我正在使用一个网站分析器,它将用于根据tomcat的日志分析我们自己的网站。
现在,我们每天将日志从tomcat推送到数据库(MySQL),现在运行良好。但是我发现了一个潜在且致命的问题!
到目前为止,我们将日志推送到数据库中的单个表,但日志项将很快迅速增加,特别是当我们拥有更多用户时,显然单个表无法保存这么多日志项(也会导致从大表执行查询操作时效果不佳。
我们使用hibernate作为持久层,日志表中的每一行都映射到应用程序中LogEntry的java对象。
我曾想过每个月都会创建一个新表,但是如何让LogEntry映射到多个表并跨表查询?
此外,每个月的日志编号可能不一样,一个极端的例子,日志编号(表中的记录)如何大于db中表的最大容量?
然后我想设置一个属性来限制hibernate push log to db时要推送的最大日志数。如果是这样,我不知道告诉hibernate自动创建一个新表和查询表。
有什么想法吗?
更新桑迪:
我知道你的意思,也就是说表的最大功能是由操作系统决定的,如果我使用分区,最大功能可能会增加,直到达到我磁盘的最大功能。但是,即使我使用分区,似乎我也不需要关心表的最大功能,但如果表中包含太多记录,则会导致性能低下。 (顺便说一句,我们还没有决定删除旧的日志。)我认为的另一种方式是创建比具有相同结构的表更多,但我使用的是hibernate,所有的日志插入和查询都将通过hibernate,并且可以实体(POJO)映射到多个表?
答案 0 :(得分:2)
我曾想过每个月都会创建一个新表,但是如何让LogEntry映射到多个表并跨表查询?
查看Hibernate Shards(数据库分片是一种水平分区方法)。虽然这个项目不是非常活跃并且有一些限制(参考文档),但是它稳定且可用(来自谷歌的Hibernate Shards已contributed by Max Ross在内部使用它。)
另外,每个月的日志编号可能不一样,一个极端的例子,日志编号(表中的记录)如何大于db中表的最大容量?
监控您的数据库/表并预测所需的维护。
如果是这样,我不知道hibernate会自动创建一个新表和查询表。
Hibernate不会自动执行此操作,这将是数据库维护和分片配置的一部分(另请参阅有关Virtual Shards的部分)。
答案 1 :(得分:1)
我认为你应该考虑横向分区。
水平分区
这种形式 分区段表行如此 不同的物理群体 可以形成基于行的数据集 单独处理(一个 分区)或集体(一对一) 分区)。所有列都定义为a 每组中都有表格 分区所以没有实际的表 属性丢失了。一个例子 水平分区可能是一个 包含十年价值的表 历史发票数据 划分为十个不同的 分区,每个分区 包含一年的价值 data.data。
提高性能 - 扫描期间
操作,MySQL优化器知道 什么分区包含数据 将满足特定的查询和 只会访问那些必要的 查询执行期间的分区。的 对于 例如,可能有一百万行表 分成十个不同的 范围样式的分区使每个 分区包含100,000行 。 *如果是 发出只需要数据的查询 从其中一个分区,和 表扫描操作是必要的, 只能访问100,000行 而不是一百万。显然,它是 MySQL可以更快地进行采样 10万行比100万行所以 查询将很快完成。该 应该得到相同的利益索引 可以作为本地访问 为其创建分区索引 分区表。最后,它是 可以对分区表进行条带化 跨越不同的物理驱动器 指定不同的文件 特定的系统/目录路径 分区。这允许物理I / O. 争论在多重时减少 分区是相同的访问 时间。
查看此文章Improving Database Performance with Partitioning
似乎水平分区可以处理大表,但是如果记录的数量大于表的最大大小呢?
实际上,mysql表的最大大小由操作系统约束决定。看看this,并确定自己。 备选方案是定期清除旧日志记录,只要它们不是分析所必需的。 创建一个cron作业或任何计划任务来进行删除。