Mysql:table 中有 70 亿条记录
Mysql: 7 billions records in a table
我需要在 Mysql table 中保存大约 78 亿条记录。 Table 是读写密集型的。我必须保持每小时至少 0.2 亿条记录的插入率。虽然搜索 table 不应超过 10 秒。
我们有一个 UI,用户可以从中根据不同的列进行搜索 属性。
搜索最多的查询可以是:
select * from mytable where prop1='sip:+100008521149' and
prop2='asdsa'
order by event_timestamp desc limit 10;
select * from mytable where prop1='sip:+100008521149'
order by event_timestamp desc limit 10;
select * from mytable where prop2='asdsa'
order by event_timestamp desc limit 10;
目前 table 上有 2 个索引:
1- idx_1(prop1,event_timestamp)
2- idx_2(prop2,event_timestamp)
InnoDB设置如下:
innodb_buffer_pool_size = 70G
innodb_log_file_size = 4G
innodb_io_capacity=2000
innodb_io_capacity_max=6000
innodb_lru_scan_depth=2000
innodb_flush_log_at_trx_commit=2
innodb_log_buffer_size=16M
innodb_thread_concurrency = 0
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_autoinc_lock_mode = 2
bulk_insert_buffer_size=33554432
query_cache_type=1
query_cache_size=64M
innodb_flush_neighbors=0
expire_logs_days=10
max-connections=500
long_query_time = 5
read_buffer_size=16M
sort_buffer_size=16M
read_rnd_buffer_size=16M
innodb_doublewrite = 0
innodb_flush_method=O_DIRECT
Machine's RAM size is 99 GB.
启动后系统很快,但当记录达到2.2亿时性能下降很多。虽然我们正在使用 LOAD INFILE,但在搜索索引参数时插入率非常 slow.Search 非常快。看来缓冲池不够了。
我有几个问题:
这个配置能支持这种数据吗
7的理想和实用的缓冲池大小应该是多少
亿条记录。
- DATA+INDEX 大小接近 150 GB,只有 2.2 亿
记录。看来我需要 TB 的 ram。
- 我们正在考虑Master/Slave配置来制作用于读取和
在各自的服务器上写显性。
- 还有其他更好的方法来设计这个解决方案吗?
- 增加更多索引使UI搜索更好但增加单个
索引使插入速度降低了很多倍。
更新:1
问- table 比 RAM 大得多,对吗? buffer_pool 不能做得足够大 -- 它必须小于 ram,否则性能会受到影响。
A- RAM 大小为 100 GB,缓冲池为 70 G。是的,数据大小比 RAM 大。
Q- 请提供 SHOW CREATE TABLE;我需要调查几个问题。 (数据类型、字段大小等)
A- 所有字段均为字符串类型。我们都使用了 varchar(127)。 PK 是自动生成的 id bigint(20).
Q- LOAD DATA INFILE 中有多少条记录?你直接加载到table吗? LOAD 的频率是多少?
A- 每个文件 100000 条记录。多个线程正在将数据从 CSV 文件加载到数据库。在初始迁移中,我们必须不断加载它直到 6.5 亿条记录。之后频率将降低到每 15 分钟一次左右。
Q- Master+Slave:请记住,所有写操作也是在 Slave 上执行的。如果你有很多读取,那么不止一个 Slave 会分散读取,从而获得一些缩放。
A- 我们目前正在使用 MASTER/SLAVE 方法进行测试。
我们用 MYISAM 创建了 MASTER,没有索引。 MASTER 将用于插入。
SLAVE 有 INNODB 和 2 个索引。将对其执行搜索。
两者都是不同的机器,不共享 RAM 或 CPU。
该应用程序在第三台机器上。
问- 你们有旋转驱动器吗?还是固态硬盘?
A-如何检查?
问- 您的行似乎很大。是否有 TEXT 或 BLOB?如果是这样,SELECT * 可能是一个严重的性能负担。
A- 是的,行有 50 列,但数据大约有 15-20 列。我们不能减少数据类型的大小,因为所有字段都可以容纳任意数量的字母数字数据。都是 TEXTS 没有 BLOBS。
这不是答案,但我无法在评论中格式化它
你能试试看它是否更快。所以 MySQL 不能仅对 id (Primary KEY)
的孔行进行排序
SELECT r.*
FROM (
SELECT id
FROM mytable
WHERE
prop1='sip:+100008521149'
AND
prop2='asdsa'
ORDER BY event_timestamp DESC
LIMIT 10
) AS r
LEFT JOIN mytable m ON m.id =r.id
ORDER BY r.event_timestamp DESC;
关闭查询缓存:它必须在每次 INSERT
发生时清除 QC 中的所有条目——即每秒 5555 次!
query_cache_type = 0
query_cache_size = 0
第一个查询需要 INDEX(prop1, prop2, event_timestamp)
。 (prop1 和 prop2 可以互换。)
使用该添加的索引,三个查询中的每一个都将触及索引中不超过 10 行,并且对数据进行不超过 10 次随机(?)提取。最坏的情况下,只有大约 11 次磁盘命中。 @Bernd 的 'lazy eval' 不会让它变得更好。
table 比 RAM 大得多,对吗? buffer_pool 不能做得足够大 -- 它必须小于 ram,否则性能 会受到影响 。
请提供SHOW CREATE TABLE
;我需要调查几个问题。 (数据类型、字段大小等)
LOAD DATA INFILE
中有多少条记录?你LOAD
直接变成了table? LOAD
的频率是多少?
Master+Slave:请记住,所有写操作也是在 Slave 上执行的。如果您有很多读取,那么不止一个从属设备会分散 读取 ,从而获得一些缩放。
你们有旋转驱动器吗?还是固态硬盘?
您的行似乎很大。有TEXTs
或BLOBs
吗?如果是这样,SELECT *
可能是一个严重的性能负担。
我通过用 Elasticsearch 替换 MYSQL DB 来实现这个要求。它看起来非常适合快速插入率和该死的快速搜索。此外,Lucene 的全文功能使其成为一个完美的工具。
ES 最好的部分是它对硬件的要求非常低。它水平缩放而不是垂直缩放。
我需要在 Mysql table 中保存大约 78 亿条记录。 Table 是读写密集型的。我必须保持每小时至少 0.2 亿条记录的插入率。虽然搜索 table 不应超过 10 秒。 我们有一个 UI,用户可以从中根据不同的列进行搜索 属性。
搜索最多的查询可以是:
select * from mytable where prop1='sip:+100008521149' and prop2='asdsa' order by event_timestamp desc limit 10;
select * from mytable where prop1='sip:+100008521149' order by event_timestamp desc limit 10;
select * from mytable where prop2='asdsa' order by event_timestamp desc limit 10;
目前 table 上有 2 个索引:
1- idx_1(prop1,event_timestamp)
2- idx_2(prop2,event_timestamp)
InnoDB设置如下:
innodb_buffer_pool_size = 70G
innodb_log_file_size = 4G
innodb_io_capacity=2000
innodb_io_capacity_max=6000
innodb_lru_scan_depth=2000
innodb_flush_log_at_trx_commit=2
innodb_log_buffer_size=16M
innodb_thread_concurrency = 0
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_autoinc_lock_mode = 2
bulk_insert_buffer_size=33554432
query_cache_type=1
query_cache_size=64M
innodb_flush_neighbors=0
expire_logs_days=10
max-connections=500
long_query_time = 5
read_buffer_size=16M
sort_buffer_size=16M
read_rnd_buffer_size=16M
innodb_doublewrite = 0
innodb_flush_method=O_DIRECT
Machine's RAM size is 99 GB.
启动后系统很快,但当记录达到2.2亿时性能下降很多。虽然我们正在使用 LOAD INFILE,但在搜索索引参数时插入率非常 slow.Search 非常快。看来缓冲池不够了。
我有几个问题:
这个配置能支持这种数据吗
7的理想和实用的缓冲池大小应该是多少 亿条记录。
- DATA+INDEX 大小接近 150 GB,只有 2.2 亿 记录。看来我需要 TB 的 ram。
- 我们正在考虑Master/Slave配置来制作用于读取和 在各自的服务器上写显性。
- 还有其他更好的方法来设计这个解决方案吗?
- 增加更多索引使UI搜索更好但增加单个 索引使插入速度降低了很多倍。
更新:1
问- table 比 RAM 大得多,对吗? buffer_pool 不能做得足够大 -- 它必须小于 ram,否则性能会受到影响。
A- RAM 大小为 100 GB,缓冲池为 70 G。是的,数据大小比 RAM 大。
Q- 请提供 SHOW CREATE TABLE;我需要调查几个问题。 (数据类型、字段大小等)
A- 所有字段均为字符串类型。我们都使用了 varchar(127)。 PK 是自动生成的 id bigint(20).
Q- LOAD DATA INFILE 中有多少条记录?你直接加载到table吗? LOAD 的频率是多少?
A- 每个文件 100000 条记录。多个线程正在将数据从 CSV 文件加载到数据库。在初始迁移中,我们必须不断加载它直到 6.5 亿条记录。之后频率将降低到每 15 分钟一次左右。
Q- Master+Slave:请记住,所有写操作也是在 Slave 上执行的。如果你有很多读取,那么不止一个 Slave 会分散读取,从而获得一些缩放。
A- 我们目前正在使用 MASTER/SLAVE 方法进行测试。
我们用 MYISAM 创建了 MASTER,没有索引。 MASTER 将用于插入。 SLAVE 有 INNODB 和 2 个索引。将对其执行搜索。 两者都是不同的机器,不共享 RAM 或 CPU。 该应用程序在第三台机器上。
问- 你们有旋转驱动器吗?还是固态硬盘? A-如何检查?
问- 您的行似乎很大。是否有 TEXT 或 BLOB?如果是这样,SELECT * 可能是一个严重的性能负担。
A- 是的,行有 50 列,但数据大约有 15-20 列。我们不能减少数据类型的大小,因为所有字段都可以容纳任意数量的字母数字数据。都是 TEXTS 没有 BLOBS。
这不是答案,但我无法在评论中格式化它
你能试试看它是否更快。所以 MySQL 不能仅对 id (Primary KEY)
的孔行进行排序SELECT r.*
FROM (
SELECT id
FROM mytable
WHERE
prop1='sip:+100008521149'
AND
prop2='asdsa'
ORDER BY event_timestamp DESC
LIMIT 10
) AS r
LEFT JOIN mytable m ON m.id =r.id
ORDER BY r.event_timestamp DESC;
关闭查询缓存:它必须在每次 INSERT
发生时清除 QC 中的所有条目——即每秒 5555 次!
query_cache_type = 0
query_cache_size = 0
第一个查询需要 INDEX(prop1, prop2, event_timestamp)
。 (prop1 和 prop2 可以互换。)
使用该添加的索引,三个查询中的每一个都将触及索引中不超过 10 行,并且对数据进行不超过 10 次随机(?)提取。最坏的情况下,只有大约 11 次磁盘命中。 @Bernd 的 'lazy eval' 不会让它变得更好。
table 比 RAM 大得多,对吗? buffer_pool 不能做得足够大 -- 它必须小于 ram,否则性能 会受到影响 。
请提供SHOW CREATE TABLE
;我需要调查几个问题。 (数据类型、字段大小等)
LOAD DATA INFILE
中有多少条记录?你LOAD
直接变成了table? LOAD
的频率是多少?
Master+Slave:请记住,所有写操作也是在 Slave 上执行的。如果您有很多读取,那么不止一个从属设备会分散 读取 ,从而获得一些缩放。
你们有旋转驱动器吗?还是固态硬盘?
您的行似乎很大。有TEXTs
或BLOBs
吗?如果是这样,SELECT *
可能是一个严重的性能负担。
我通过用 Elasticsearch 替换 MYSQL DB 来实现这个要求。它看起来非常适合快速插入率和该死的快速搜索。此外,Lucene 的全文功能使其成为一个完美的工具。 ES 最好的部分是它对硬件的要求非常低。它水平缩放而不是垂直缩放。