注意:
我们希望将“logs”存储在一个表中,该表包含以下最小字段集(为了优化目的,可能会添加更多字段):
消息列具有以下特征
* 99%的时间非常短(<64个字符,但是例外情况它们可能很长&gt; 1024个字符)
*一些识别良好的消息可能占用消息数量的10%
*许多“近乎”重复的消息(即this system hs been up and running for X seconds
)
*长尾的“独特”消息
*获取典型日期的消息并通过gzip运行它们很容易将大小除以15
现在我正在考虑两种可能的解决方案
我们的想法是拥有某种压缩算法,该算法可以根据我们识别的“重复文本”列表使用用户提供的“词典”并存储结果。由于我们的“应用程序”是唯一一个可以写入和读取的应用程序,因此我们可以“动态”解压缩
_
_
对于这类问题,是否已有“最先进”的解决方案?
答案 0 :(得分:1)
我终于选择了dictionnary表的想法
对于dictionnary_id我实际上使用了murmurhash 64 bits
(并命名为id hash_message
,这样我就可以先在python端预先计算它,因为它是非加密的,它是&#39;非常适合调用,对于python来说,它是mmh3
模块的纯C实现。
我预装了dictionnary表,其中包含我从#34;典型的一天&#34;中获得的507百万条消息中的500k最常见(和重复)的日志。的日志。
然后我加载了执行以下INSERT
请求的数据:
INSERT INTO my_logs (
service_id,
creation_date,
level,
hash_message,
message
)
SELECT
%(hash_robot)s,
%(creation_date)s,
%(hash_message)s,
NULLIF (
%(message)s,
min(message)
)
FROM dictionnary
WHERE hash_message = %(hash_message)s;
通过这样做,如果message
已经存在,则自动插入,并且只有在我的日志表中插入实际文本(如果它不存在于字典中)。
我的日志表的message
列使用的平均值只有3个字节!这意味着大多数情况下消息表为空,虽然在我的dictionnary中添加更多日志是不值得的(并且从bigint
为我的service_id切换到int
实际上是一个更好的主意)