概述
我每天都要存储以这种方式创作的1亿条记录:CCD_ 1。唯一密钥是id
,但我必须在name
和time
上进行搜索。
我不得不选择一个像MongoDb、Cassandra或其他数据库,但我不知道它们的性能,以便在数据库中写入这些日志并检索它们。
我的必要性是,写作操作非常非常快,也比阅读/搜索更快。我希望使用索引来更快地进行搜索,并且我可以使用一些集群来分割数据,比如mongoDB中的shard。
我的硬件性能不太好,我使用Docker,在SSD技术中,每个容器最多可以有8G字节的ram和500GB的硬盘。操作系统是Ubuntu。容器不能停留在同一台机器上,它们通过局域网进行通信。
我想知道哪个数据库写日志最快。
数据库的架构
数据库由两个表组成:
- 主表(命名为表A)由以下部分组成:
id
是一个最多30个字符的字符串,它是主键name
是一个最多60个字符(从30到60个字符)的字符串,它有一个索引来执行搜索,并且它是唯一的关键字time
是一个最多60个字符(从30到60个字符)的字符串,它有一个索引来执行搜索,并且它是唯一的关键字
输入是非常非常长的文件(1000万条记录),每天都会给出这些输入文件。
一年后,该表将是365 x 100^6元组,两年后将是2 x 365 x 100 ^6,到目前为止。
- 形成第二个表(命名为表B):
field
是一个最多包含60个字符的字符串(从30到60个字符)
此表每两小时或更长时间更新一次(添加或删除元组)。
查询
主要请求是:
select *
from A, B
where field = time OR field = name
并且每当表B被更新时或者如果不可能的话每天都进行该请求。但是搜索的持续时间不能超过1小时。
对我来说,最重要的一点是,当数据库必须导入表A上的文件时,它非常非常快。我也可以接受在搜索运行时停止插入表A和更新表B。但是,当我把文件中的新记录放在表A上时,我不能慢下来。插入新记录(或导入文件)时,速度必须尽可能快。
其他信息
我希望有一天也能像RAID 1一样插入复制数据,以确保不会丢失任何数据。
在SSD上有新闻,以避免任何数据丢失。
每秒插入的行记录数必须尽可能快。这是我的问题中最重要的关键问题。
每秒插入120行。他们一排一排地到达吗?还是一次花一整天?还是别的什么?
记录来自一些文件,每个文件都有很多记录。在inf之前,记录数可以是1。文件有时到达,没有特定的时间段。但我有可能在插入新文件之前等待几个小时,以便处理它(可能将格式从CSV更改为JSON,或者对格式进行一些检查),或者如果数据库正在导入以前的文件。
它是一个";log";文件还是CSV?还是别的什么?请提供样品。
输入文件可以是CSV、JSON文件或其他文件。我有可能在进口之前对此进行修改。文件的示例可以是:
id, name, time
9999999999999 AAAAAAAAAAAAAAAA 18Agust201819h90m90s
1233423434333 zzzzzzzzzzzzzzzzz Monday18Agust201819h90m91s
000244200002 BAJDHFURI8DNCJUED sds3444324sssdds34343ddff
0000000000003 ZXEWSFFSJFajf8392 Monday18Agust201819h90m94s
1123884000334 1AAAAAAAAAAAAAAAA Monday18Agust101819h90m95s
3334442000005 1zz2zz244z34sASd3 fff3320000001010101011111s
- 文件的大小可以是10Gbyte或更大或更小,没有特定的规则。但我可能要等几个小时才能合并一些文件并导入一个大文件
id
是自己的id- CCD_ 10是一个特殊的";hash";部门/应用程序/用户提供给数据库的日志
什么样的"时间";是否以36-60个字符串的形式提供?请提供样品。
id name time
1实际上是一个通用字符串,因为每个应用程序/部门/办公室都有自己的格式。但在这种情况下也可以被认为是一种特殊的";散列";。
每天1000万行-->500GB。那么磁盘将在一年内填满?需要更改哪些部分来处理您期望接收的数据?
所有这些日志都无法修剪。这个数据库是企业的一个数据湖,用来收集所有的日志。
您会在90天后清除数据吗?(这将解决我之前的观点,但需要一个特殊的模式来提高效率。)
无法修剪所有这些行。
where field = time OR field = name
不实用。请用文字描述其意图。我们需要用其他方式表达查询。
有时我们会收到要在TABLE A
中搜索的文件,但我们无法知道该字符串是链接到字段NAME
还是TIME
。因为这个文件是由一个非常旧的应用程序创建的。
100^6 = 100*100*100*100*100*100
=1万亿。我不认为你是那个意思。
是的,我认为这是一个乐观的数字:(现在我的办公室每小时收集5G字节的几种格式的日志(JSON、CSV等)。我们正处于发展阶段。最后一个场景是所有日志都存储在这个数据库中。我认为最大pick也可以是每小时50Gbyte。
过去,所有日志都是在普通硬盘中收集的。在10年的时间里,我的部门已经收集了大约100TByte的数据,但只针对旧的部门和办公室。现在有了新的部门,所以我想我们会有比以前更多的日志。
该项目的目标是在一个数据库中收集社会的所有日志,例如,当用户Alpha打开了一台计算机,或者用户登录查看电子邮件和其他更多信息时。或者,如果用户希望创建一个特殊的日志来进行证明。但这只是这个数据库应用的一个例子。另一个是数据库是来自其他数据库的共享数据库。
例如:用户Bravo向Tango发送了一封电子邮件。Tango声称Bravo没有这么做。Bravo可以使用他的部门日志数据库检索日志。现在Bravo问我们是否有一个特定的元组,如果元组存在于自己的数据库中,Bravo有发送邮件的证据。
(还不是答案,但对于注释来说太长了。)
- 每秒插入120行。他们一排一排地到达吗?还是一次花一整天?还是别的什么
- 它是一个";log";文件还是CSV?还是别的什么?请提供样品
- 什么样的";时间";是否以36-60个字符串的形式提供?请提供样品
- 每天10M行-->500GB。那么磁盘将在一年内填满?需要更改哪些部分来处理您期望接收的数据
- 你会在90天后清除数据吗?(这将解决我之前的观点,但需要一个特殊的模式来提高效率。)
- CCD_ 17不实用。请用文字描述其意图。我们需要用其他方式表达查询
- CCD_ 18=CCD_ 19=1万亿。我不认为你是那个意思
(解决大多数问题…)
-
RAID,驱动器"日志记录";,等等是数据丢失风险的部分解决方案。它们是在较低级别处理的;SQL或MySQL配置中的任何内容都与此无关。
-
每个CSV文件(行数为1到INF)最好通过
LOAD DATA
加载。可以直接将其加载到主表中更好,或者可能最好将其加载在临时表中,按摩数据,然后将其复制到主表。(我没有足够的细节来预测哪一个更好。) -
直接加载到主表中的巨大CSV文件可能会阻止一些操作。在这种情况下,浏览临时表可能很重要。然后,可以将行分块复制到主表中,从而将影响降至最低。关于分块的更多信息:http://mysql.rjweb.org/doc.php/deletebig#deleting_in_chunks(这谈到了
DELETE
,但可以很容易地适应应用程序中所需的SELECT
。) -
你说
time
本身就是独一无二的?不是两件事可以在同一秒内发生吗? -
name
和time
是唯一的?在CCD_ 26和CCD_。UNIQUE
将减慢INSERT
的速度,因为在完成插入之前需要检查唯一性。对于您的申请,我(还)看不出UNIQUE
比INDEX
有任何好处。 -
"异常";时间";format——不要计划进行除
=
之外的范围或比较。正如你所说,把它想象成一个"杂碎"。 -
不修剪?数据在这个表中保存了多年?那么,如果磁盘空间以500GB/年的速度增长,你会怎么处理呢?
-
你会有
INDEX(name), -- (or UNIQUE(name)) INDEX(time) -- (or UNIQUE(time))
-
出于性能考虑,您建议的查询应更改为此查询。(
?
将变成相同的引号"hash"。)SELECT * FROM A WHERE name = ? UNION ALL SELECT * FROM A WHERE `time` = ?
-
CCD_ 34可能需要基于其来源的日志文件的某种时间戳。我希望一些查询能得到数千个结果,而用户可能只想要";最近的";后果[好吧,这与您关于
name
和time
是唯一的声明相冲突,在这种情况下,上面的Select只能返回1或2行。] -
即使
A
变为数TB,上面的Select(带有上面的索引)也将始终以毫秒为单位运行(假设最多有2个结果行)。RAM大小基本上对速度没有影响。磁盘必须足够大,可以容纳整张桌子。此外,由于HDD仍然比SSD便宜,因此在巨大的桌子上使用HDD可能是值得的。(无论配置如何,查询可能仍需要不到1.0秒的时间。) -
如果您希望该表大于32TB,我们需要做一些额外的工作。这是一个严格的限制,但有办法绕过它。如果这将是一个问题,请开始一个新的问题,只关注表大小(加上表架构和主选择)。行数不会达到限制,只是字节大小。
-
由于新的";log";每小时(或任何时候)到达;最新";。也就是说,Select找不到最近一个小时左右发生的记录。因此,我不担心CSV的加载是否需要一个小时。";块化";我上面提到的增加了一点时间,同时避免了堵塞。因此,我强烈认为,分块是";右";基于数据流和其他要求的方法。
-
id
是什么时候生成的?它曾经";使用";?是否包括日志的名称?我这么问是因为:它需要空间,可能会减慢速度,你不需要一个";日志id";,也许它可以被丢弃,有比varchar(60)更好的东西可以作为PK,等等。