3亿数据快速检索实现
上周有个需求,就是要做一个检索库:
1 3亿个手机号码,并且每个号码20个左右的属性例:地区,订阅等信息。
2 在最短的时候内select出来(5分钟,10分钟)[最重要]
3 允许更新。对这些号码进行发送信息后,状态改变。[可以让他慢慢更新]
和几个同事讨论了一下,具体要注意以下几点:
1 如果发送下去状态改变,但是只发送一半,但状态改变了如何办?
2 如果多个产品线一起下发,状态会不会混乱。
解决以上第二个问题,决定采用,队列等待的方式。第一个问题没想到好的解决办法,回滚也想过了,但感觉不是很现实!
解决方案:
经过实验500w条的数据在用plsql直接select,只需要0.2秒,所以总体采用分表的方式,每500w条分一个表,然后同时查询!
但总感觉不是很好,抛砖引玉(真的很砖
)。不知道大家有没有更好的解决方案!
-----------------------------------------重新描述一下需求-------------------------------
很多人说需求不是很的清楚,这里重新整理了一下!
不过要注意的是数据库里已经有3亿个手机基数了!
一.号码入库。
不定期会有新的号码需要入库,入库需要记录号码的常规属性,如:手机号,省份,城市,入库时间,手机卡类型,是否支持彩信,号码来源情况等。
二.入库手机号源文件管理
入库手机号源文件要以文件形式保存在服务器上。
三.按需要提取号码(最关键部分)
要按照需求提取所需的号码。
例如:
提号要求:
1.此号码非黑名单用户。
2.此号码为的订购和退订用户。
3.此号码2个月内没有活动。
4.省份要求:辽宁,云南,广东
5.号段要求:137和138和139号段
6.数量要求:每个省10w
7.是否支持彩信:是(是,否,忽略三种情况)
……
最后,符合条件的号码,按照固定格式(每个手机号占一行),形成文本文件,将此文件测试号码,是否需要状态报告等信息形成最终可发送文件并提供下载功能,同时记录本次提取信息(发送时间,发送标识等)
注:文件格式如下:
139***85185#09#0
139***71283
139***33190
第1列:手机号
第2列:产品类型(#09)
第3列:是否需要状态报告(#0)
四.统计功能
一.号码情况统计
1.统计当前号码总量。
2.按照2个基本要求,统计现在库中可以使用的号码数量。
注:统计需要显示,全国总量,各省总量,各省省会总量,各省去除省会总量,各省7天未下发总量(省会与其他城市分开显示),各省可以发送总量(省会与其他城市分开显示,所以单独列出来)。
二.发送产品统计
1.按时间段、业务线等统计发送产品的情况,如:发送时间,最终发送文件等
五.黑名单及特殊号码管理
1.添加黑名单
2.去除黑名单
3.过滤黑名单
4.查询黑名单
以上除黑名单外都是迫切需要的,黑名单功能可以以后完善。
64 楼 Auckland 2009-05-26 抛出异常的爱 写道天机老人 写道机器只会有一台。不用考虑多台机器的事情!
公司要的就是价值最大化!不然这个活也不会交到我们手里了!
放文件里吧....
不同的属性不同的文件夹.
规则成树状
大量的移动使用文件move
少量的移动把文件中对应的手机号删除新建.
看来看去还是觉得抛出异常的爱的建议不错。
其次,我觉得你的瓶颈不仅仅在数据库更新上。
65 楼 dmewy 2009-05-26 数据库更新其实很好解决.
不知道你们有没有DataExchange的概念.
可以create一个新表去Insert.
等到晚上的时候再update回主表.
66 楼 抛出异常的爱 2009-05-26 Auckland 写道抛出异常的爱 写道天机老人 写道机器只会有一台。不用考虑多台机器的事情!
公司要的就是价值最大化!不然这个活也不会交到我们手里了!
放文件里吧....
不同的属性不同的文件夹.
规则成树状
大量的移动使用文件move
少量的移动把文件中对应的手机号删除新建.
看来看去还是觉得抛出异常的爱的建议不错。
其次,我觉得你的瓶颈不仅仅在数据库更新上。
最大难点在于规则方案少....
检索慢...不过5分钟应该足够用了
dmewy 写道数据库更新其实很好解决.
不知道你们有没有DataExchange的概念.
可以create一个新表去Insert.
等到晚上的时候再update回主表.
一秒100TPS一宿也update不了多少. 67 楼 dmewy 2009-05-26 抛出异常的爱 写道Auckland 写道抛出异常的爱 写道天机老人 写道机器只会有一台。不用考虑多台机器的事情!
公司要的就是价值最大化!不然这个活也不会交到我们手里了!
放文件里吧....
不同的属性不同的文件夹.
规则成树状
大量的移动使用文件move
少量的移动把文件中对应的手机号删除新建.
看来看去还是觉得抛出异常的爱的建议不错。
其次,我觉得你的瓶颈不仅仅在数据库更新上。
最大难点在于规则方案少....
检索慢...不过5分钟应该足够用了
dmewy 写道数据库更新其实很好解决.
不知道你们有没有DataExchange的概念.
可以create一个新表去Insert.
等到晚上的时候再update回主表.
一秒100TPS一宿也update不了多少.
这个就简单了.首先你是用当天insert的哪张表去update所以不是3亿数据都UPDATE.
小表join大表去update.
OK.不过我基本上都不用update.因为update是一条一条去做的.
没关系.还是很easy.
基本的做法是根据PK去delete然后再 addbatch insert.
delete的时候用exist .这些都是小技巧了.
技巧很多很多. 比如insert的时候先drop index 全部insert以后再create index.
问题是楼主的需求他自己估计都搞不懂.
PS:我本来是做web开发的,现在主要负责DataExchange的部分.
68 楼 jichongchong 2009-05-26 GT07 写道jichongchong 写道我们用了hash+文件+内存,没用关系数据库,用户属性都是动态的-_-!
这种方案之前我们都讨论过,你们是怎么实现复杂查询的?
没有Index,你说怎么查的-_-! 69 楼 抛出异常的爱 2009-05-26 dmewy 写道抛出异常的爱 写道Auckland 写道抛出异常的爱 写道天机老人 写道机器只会有一台。不用考虑多台机器的事情!
公司要的就是价值最大化!不然这个活也不会交到我们手里了!
放文件里吧....
不同的属性不同的文件夹.
规则成树状
大量的移动使用文件move
少量的移动把文件中对应的手机号删除新建.
看来看去还是觉得抛出异常的爱的建议不错。
其次,我觉得你的瓶颈不仅仅在数据库更新上。
最大难点在于规则方案少....
检索慢...不过5分钟应该足够用了
dmewy 写道数据库更新其实很好解决.
不知道你们有没有DataExchange的概念.
可以create一个新表去Insert.
等到晚上的时候再update回主表.
一秒100TPS一宿也update不了多少.
这个就简单了.首先你是用当天insert的哪张表去update所以不是3亿数据都UPDATE.
小表join大表去update.
OK.不过我基本上都不用update.因为update是一条一条去做的.
没关系.还是很easy.
基本的做法是根据PK去delete然后再 addbatch insert.
delete的时候用exist .这些都是小技巧了.
技巧很多很多. 比如insert的时候先drop index 全部insert以后再create index.
问题是楼主的需求他自己估计都搞不懂.
PS:我本来是做web开发的,现在主要负责DataExchange的部分.
好办法... 70 楼 uptorun 2009-05-26 抛出异常的爱 写道dmewy 写道抛出异常的爱 写道Auckland 写道抛出异常的爱 写道天机老人 写道机器只会有一台。不用考虑多台机器的事情!
公司要的就是价值最大化!不然这个活也不会交到我们手里了!
放文件里吧....
不同的属性不同的文件夹.
规则成树状
大量的移动使用文件move
少量的移动把文件中对应的手机号删除新建.
看来看去还是觉得抛出异常的爱的建议不错。
其次,我觉得你的瓶颈不仅仅在数据库更新上。
最大难点在于规则方案少....
检索慢...不过5分钟应该足够用了
dmewy 写道数据库更新其实很好解决.
不知道你们有没有DataExchange的概念.
可以create一个新表去Insert.
等到晚上的时候再update回主表.
一秒100TPS一宿也update不了多少.
这个就简单了.首先你是用当天insert的哪张表去update所以不是3亿数据都UPDATE.
小表join大表去update.
OK.不过我基本上都不用update.因为update是一条一条去做的.
没关系.还是很easy.
基本的做法是根据PK去delete然后再 addbatch insert.
delete的时候用exist .这些都是小技巧了.
技巧很多很多. 比如insert的时候先drop index 全部insert以后再create index.
问题是楼主的需求他自己估计都搞不懂.
PS:我本来是做web开发的,现在主要负责DataExchange的部分.
好办法...
可以使用批处理进行更新,但是要注意失误便捷不要划分的太大,否则占用大量回滚段资源,也会影响性能,另外,update语句的更新条件最好能减少使用等值,也有利于更新的速度 71 楼 天机老人 2009-05-27 太感谢大家了,想不大家都如此热情!
特别是老抛同学真是太热心了。不知道说啥好呢! 72 楼 zelsa 2009-06-01 Lucene完全可以搞定,数据又不是很多,索引在update数据时实时更新度没问题的。直接用Hibernate Search或Compass吧,肯定能满足。 73 楼 redhat 2009-06-01 这个使用水平切分数据库可以达到目的,使用读写分离技术进一步提高性能。
一点建议:
这个应用业务相对于简单,可以自己写一个简单的dal层。
你可以对于切割数据库:对于手机号进行水平分割。
对于修改,和查询进行预编译,使之关联到各个table进行查询或修改。
不过可以尝试使用hibernate shards,应该更加方便一点。 74 楼 elmar 2009-06-01 土土的问:为什么不直接使用3亿条数据,置标志位的方式实现 300M*300字节=100G数据文件的直接访问。 75 楼 elmar 2009-06-01 天机老人 写道按照我们的方案,大批量的查是没啥问题!但是大批量的更新非常成问题!
速度实在是难以想象!每更新一条就要开启关闭一次事物!
所以还是想听听大家的意见!
数据库无事务吧……应用程序做 76 楼 0000 2009-06-01 我知道垃圾短信是哪来的了。。 77 楼 fjlyxx 2009-06-02 楼主可以参考 防火墙,安全隐患策略类型软件的数据格式 用块状数据去存储 不一定要用数据库. 因为你有手机号码 所以你可以做到按手机号码排序 这样用文件去做更新是很快的 你想防火墙过滤规则的数据量是不会小的 但是为什么他们能做到这么快... 78 楼 swit1983 2009-06-09 弱弱的问一下,大家说的分区,是逻辑上的还是物理上的啊。比如是把原来的一张表分区成多张表,还是加上一个条件(比如:地区为xx)多次查询啊? 79 楼 funcreal 2009-06-17 我知道oracle可以按照日期进行分区,分区后速度很快。但不知道能不能按照手机号码进行分区? 80 楼 抛出异常的爱 2009-06-17 funcreal 写道我知道oracle可以按照日期进行分区,分区后速度很快。但不知道能不能按照手机号码进行分区?
不用想了工信发文了...以后做这行不用考虑成本了...买几个服务器吧. 81 楼 src_bord 2009-06-26 dmewy 写道数据库更新其实很好解决.
不知道你们有没有DataExchange的概念.
可以create一个新表去Insert.
等到晚上的时候再update回主表.
呵呵! 不错. 这解决方案挺好的.在数据量非常大的情况下,白天把用户需要更新的数据记录下来,晚上空闲时候在去update,这样效率上虽然好不到哪去,但是,时间安排的好....
82 楼 zhaojuan8 2009-06-26 数据切分吧
前面不是有人发过一个数据切分的帖子么
另外楼主发帖没有说明数据库环境 83 楼 zjjvalid 2009-07-25 如果是oracle 可以建立分区表 为了更平均 可以按照手机号最后一位 就可以每个标有3千万 如果还有问题 可以后两位分就每个表3百万 已经很小了。
2、更新数据 尽量减少 可以弄个表做插入 例如只更新是否发送了 网关的响应和状态报告都可以扔到另外的表里
3、我想3亿条数据你也不会每天都发 如果每天发1千万 这种做法可定没有问题
4、用户的添加我想 对于时间不会有太高要求 差不多就行了 所以索引一定要建好 当然也不需要太多