我目前正在编写一个应用程序,我必须存储大量的数据。我的应用程序是用Node.js编写的,我使用集群和异步模块来利用我的完整系统。
下面是我的应用程序和我正在使用的环境的一些属性:
工作站:
- CPU: 6核3.5 GHz
- 内存:16 gb Nodejs:最新版本
- 当前数据库:MySQL
- 操作系统:Windows 10
- 当前使用6个worker,每个worker占用0.1% CPU和80mb RAM
- 以JSON格式通过RPC调用为数据库获取数据
数据:
Blocks(目前为~376,000 Blocks)每~10min增加1个。单个块的数据示例:
{ "hash" : "000000000fe549a89848c76070d4132872cfb6efe5315d01d7ef77e4900f2d39", "confirmations" : 88029, "size" : 189, "height" : 227252, "version" : 2, "merkleroot" : "c738fb8e22750b6d3511ed0049a96558b0bc57046f3f77771ec825b22d6a6f4a", "tx" : [ "c738fb8e22750b6d3511ed0049a96558b0bc57046f3f77771ec825b22d6a6f4a" ], "time" : 1398824312, "nonce" : 1883462912, "bits" : "1d00ffff", "difficulty" : 1.00000000, "chainwork" : "000000000000000000000000000000000000000000000000083ada4a4009841a", "previousblockhash" : "00000000c7f4990e6ebf71ad7e21a47131dfeb22c759505b3998d7a814c011df", "nextblockhash" : "00000000afe1928529ac766f1237657819a11cfcc8ca6d67f119e868ed5b6188" }
- 事务(目前约84,850,717事务)每秒增加约1.3事务。一个事务的数据示例:
{
"hex" : "0100000001268a9ad7bfb21d3c086f0ff28f73a064964aa069ebb69a9e437da85c7e55c7d7000000006b483045022100ee69171016b7dd218491faf6e13f53d40d64f4b40123a2de52560feb95de63b902206f23a0919471eaa1e45a0982ed288d374397d30dff541b2dd45a4c3d0041acc0012103a7c1fd1fdec50e1cf3f0cc8cb4378cd8e9a2cee8ca9b3118f3db16cbbcf8f326ffffffff0350ac6002000000001976a91456847befbd2360df0e35b4e3b77bae48585ae06888ac80969800000000001976a9142b14950b8d31620c6cc923c5408a701b1ec0a02088ac002d3101000000001976a9140dfc8bafc8419853b34d5e072ad37d1a5159f58488ac00000000",
"txid" : "ef7c0cbf6ba5af68d2ea239bba709b26ff7b0b669839a63bb01c2cb8e8de481e",
"version" : 1,
"locktime" : 0,
"vin" : [
{
"txid" : "d7c7557e5ca87d439e9ab6eb69a04a9664a0738ff20f6f083c1db2bfd79a8a26",
"vout" : 0,
"scriptSig" : {
"asm" : "3045022100ee69171016b7dd218491faf6e13f53d40d64f4b40123a2de52560feb95de63b902206f23a0919471eaa1e45a0982ed288d374397d30dff541b2dd45a4c3d0041acc001 03a7c1fd1fdec50e1cf3f0cc8cb4378cd8e9a2cee8ca9b3118f3db16cbbcf8f326",
"hex" : "483045022100ee69171016b7dd218491faf6e13f53d40d64f4b40123a2de52560feb95de63b902206f23a0919471eaa1e45a0982ed288d374397d30dff541b2dd45a4c3d0041acc0012103a7c1fd1fdec50e1cf3f0cc8cb4378cd8e9a2cee8ca9b3118f3db16cbbcf8f326"
},
"sequence" : 4294967295
}
],
"vout" : [
{
"value" : 0.39890000,
"n" : 0,
"scriptPubKey" : {
"asm" : "OP_DUP OP_HASH160 56847befbd2360df0e35b4e3b77bae48585ae068 OP_EQUALVERIFY OP_CHECKSIG",
"hex" : "76a91456847befbd2360df0e35b4e3b77bae48585ae06888ac",
"reqSigs" : 1,
"type" : "pubkeyhash",
"addresses" : [
"moQR7i8XM4rSGoNwEsw3h4YEuduuP6mxw7"
]
}
},
{
"value" : 0.10000000,
"n" : 1,
"scriptPubKey" : {
"asm" : "OP_DUP OP_HASH160 2b14950b8d31620c6cc923c5408a701b1ec0a020 OP_EQUALVERIFY OP_CHECKSIG",
"hex" : "76a9142b14950b8d31620c6cc923c5408a701b1ec0a02088ac",
"reqSigs" : 1,
"type" : "pubkeyhash",
"addresses" : [
"mjSk1Ny9spzU2fouzYgLqGUD8U41iR35QN"
]
}
},
{
"value" : 0.20000000,
"n" : 2,
"scriptPubKey" : {
"asm" : "OP_DUP OP_HASH160 0dfc8bafc8419853b34d5e072ad37d1a5159f584 OP_EQUALVERIFY OP_CHECKSIG",
"hex" : "76a9140dfc8bafc8419853b34d5e072ad37d1a5159f58488ac",
"reqSigs" : 1,
"type" : "pubkeyhash",
"addresses" : [
"mgnucj8nYqdrPFh2JfZSB1NmUThUGnmsqe"
]
}
}
],
"blockhash" : "00000000103e0091b7d27e5dc744a305108f0c752be249893c749e19c1c82317",
"confirmations" : 88192,
"time" : 1398734825,
"blocktime" : 1398734825
}
问题:MySQL数据库在只使用500MB RAM的情况下将CPU推到100%。目前我的瓶颈是MySQL数据库,它无法处理我的应用程序的速度和数据量,并且占用了大量的CPU功率。
我要找的是:
一个数据库,可以处理我的应用程序,即使我增加工作数量
检索信息和选择具有依赖关系的数据应该很容易。(块通过tx <--> txid值与事务建立连接)
应该能够在未来保存更多的数据,因为数据的稳定增长
需要同时被多个worker访问
奖励:当数据发生变化时,向我的应用程序发送通知(通道)
我希望有人能给我一个建议,哪个数据库适合我的项目类型,并给我一个猜测所需的存储量。
你可以给我推荐另一个我在标题中没有提到的数据库。
当事物之间有很多关系时,关系数据库非常有用,特别是当您希望在查询时遍历这些关系时。例如,您可能有一群客户,每个客户都有许多订单,这些订单都来自各个地点的供应商;您可能希望查询从特定位置的供应商处至少有五个订单的所有客户。或者,您可能想知道按位置分组的供应商的订单总数。关系数据库在这方面非常出色。
你的数据确实有关系,是的。然而,听起来好像您并不打算遍历它们或大量聚合它们,并且您的数据一旦存储,就很少(如果有的话)更改。在我看来,文档存储更适合您。
在你列出的数据库中,MongoDB和Redis可以被认为是文档存储。你说你只有512mb的内存;Redis喜欢将所有数据存储在RAM中,并将其作为事后的想法扔到磁盘上。我不确定MongoDB试图达到什么平衡,但我相信,虽然它在一定程度上自由地使用RAM,但它最终也会尝试将其放到磁盘上。(有些人取笑它,说它在耐用性上不怎么努力。看起来您存储的数据是公开可用的,所以这应该不是一个太大的问题——如果您丢失了一些最近写入的数据,您可以从公共来源重新填充它。在评论中,你指出你通常会查询一个区块中的所有交易。MongoDB应该能够轻松处理该用例。您唯一需要确保的是在block-ID列(字段)上创建索引。我不确定MongoDB叫它们什么),这应该允许这种查询有效地执行。