这是笔者曾经的面试题,这个问题并不是要你回答准确的时间,而是考察如何设计一个系统,最快速地插入10亿条数据。
笔者当时傻乎乎地回答三小时,支支吾吾没说出所以然。面试官看我没睡醒,让我回去等通知。好在他把简历退给我了,我省了一份简历。今天尝试重新思考下,好好打他脸。
最快的速度把10亿条数据导入到数据库,首先需要和面试官明确一下,10亿条数据什么形式存在哪里,每条数据多大,是否有序导入,是否不能重复,数据库是否是MySQL?
假设和面试官明确后,有如下约束:
10亿条数据,每条数据1Kb
数据内容是非结构化的用户访问日志,需要解析后写入到数据库
数据存放在Hdfs或S3分布式文件存储里
10亿条数据并不是1个大文件,而是被近似切分为个文件,后缀标记顺序
要求有序导入,尽量不重复
数据库是MySQL
一、数据库单表能支持10亿吗?
首先考虑10亿数据写到MySQL单表可行吗?
答案是不能,单表推荐的值是W以下。这个值怎么计算出来的呢?
MySQL索引数据结构是B+树,全量数据存储在主键索引,也就是聚簇索引的叶子结点上。B+树插入和查询的性能和B+树层数直接相关,W以下是3层索引,而w以上则可能为四层索引。
Mysqlb+索引的叶子节点每页大小16K。当前每条数据正好1K,所以简单理解为每个叶子节点存储16条数据。b+索引每个非叶子节点大小也是16K,但是其只需要存储主键和指向叶子节点的指针,我们假设主键的类型是BigInt,长度为8字节,而指针大小在InnoDB中设置为6字节,这样一共14字节,这样一个非叶子节点可以存储16*/14=。
也就是每个非叶子节点可关联个叶子节点,每个叶子节点存储16条数据。由此可得到B+树索引层数和存储数量的表格。2KW以上索引层数为4层,性能更差。
更详细的请参考B+树层数计算(baijiahao.baidu.