精华内容
下载资源
问答
  • 网络支付海量数据存取处理的研究

    千次阅读 2011-11-13 22:50:18
    本文从针对网络支付带来的海量数据带来的问题,通过改进和优化数据库配置、数据分割、数据分类、处理算法、数据访问、虚拟内存和文本格式处理等方面,对网络支付带来的海量数据存取处理进行研究,提出了几个可行性的...
    (kkkloveyou  广州 广东商学院 信息学院) 
    

    摘要:随着网络购物的普及,网上支付业务蓬勃发展,同时网络支付行为带来的海量数据处理也给网络支付平台带来了巨大挑战。本文从针对网络支付带来的海量数据带来的问题,通过改进和优化数据库配置、数据分割、数据分类、处理算法、数据访问、虚拟内存和文本格式处理等方面,对网络支付带来的海量数据存取处理进行研究,提出了几个可行性的解决方案,具有实际指导作用。

    关键词:网络支付 海量数据 处理

     

    0.引言

     

    截至2010年末,国内网络支付市场规模已经突破1万亿元。根据易观智库EnfoDesk《2011年Q3中国第三方支付市场季度监测》数据报告显示,2011年第3季度中国第三方互联网在线支付市场交易规模达到5643亿,环比增长22.4%,同比增长95%[1]。伴随着互联网的普及以及中国金融支付体系的不断完善与创新,网络支付的发展进入前所未有的腾飞年代[2]。从概念上看,网络支付是电子支付的一种形式。广义地讲,网上支付是以互联网为基础,利用银行所支持的某种数字金融工具,发生在购买者和销售者之间的金融交换,而实现从买者到金融机构、商家之间的在线货币支付、现金流转、资金清算、查询统计等过程。网络支付是采用先进的技术通过数字流转来完成信息传输的,其各种支付方式都是采用数字化的方式进行款项支付的[3]。相比与传统的支付方式,网络支付具有方便、快捷、高效、经济的优势。用户只要拥有一台上网的PC机,便可足不出户,在很短的时间内完成整个支付过程。但同时,网络支付带来的海量数据,正给网络支付平台带来了巨大挑战。以第三方网上支付平台支付宝为例,仅2011年11月11日当天,便创下当天支付交易量3369万笔,比去年纪录增长了近170%。网络支付海量数据的存取处理,成为一个不可忽视的课题。

     

    1. 网络支付海量数据带来的瓶颈

     

    1.1数据存取效率低下

    网络支付数据往往呈现出线性增长,巨大的数据不断膨胀往往给应用系统带来一些难以忍受的后果, 最典型的是系统在运行过程中资源消耗需求量越来越大, 运行效率明显降低, 随着时间的推移, 达到难以忍受的程度[4]。数据访问时, 随着检索范围加大, 查询效率会显著降低,用户在查询时无法得到有效的数据后,将失去等待的耐心而逐步放弃使用系统, 使系统失去存在的意义[5]。

    1.2数据安全性、完整性不能保证

    网络支付对系统安全性完整性要求较高,以支付宝为例,2011年11月11日凌晨0:01分,支付宝在一分钟内的付款笔数就超过5.5万笔,涉及上百万资金。然而, 随着数据的积累, 数据表(Table)和数据库(DataBase)变得日渐庞大[6],系统处理和响应的速度会越来越慢越来越慢。当系统响应慢到一定程度时, 数据处理的时效性就不能满足要求, 最后可能直接导致数据丢失。比如,用户A往用户B汇入30万人民币,当用户A 点击提交转账后,系统没有及时给予转账成功的反馈。于是用户A 认为转账没有成功,再次向用户B 汇入30万人民币。最后系统将60万人民币转给了用户B ,而这并不是用户A 所期望的。

     

    2. 解决方案 

     

    实现海量数据存取的方法主要从以下几个方面入手。

    2.1数据库配置

    选用合适的数据库。数据库管理系统要确保数据的安全, 防止非法用户窃取和破坏数据, 通常系统采用身份验证、口令、密码、控制用户权限等方法保证数据安全[7]。如支护宝用户账号密码、银行账目不得非法改动等均属数据安全性范畴。网上支付海量数据处理系统一般在网络(LAN或WAN) 环境下运行。系统的安全性十分重要。选用的平台必须有完整的安全机制。目前微软公司开发的SQL server 2008和Oracle 11g等都配备了非常之强大安全防护性能, 安全机制也比较完备, 它设有登录安全性、DB 安全性、DB 对象安全性等机制。在建表时, 可设置各种约束, 在数据库中可创建规则、默认值、存储过程、触发器等DB 对象, 来保证字段和记录的有效性。

    数据库缓存的配置也相当重要,缓存大小设置的好差也关系到数据处理的成败,例如,网上支付平台在处理2 亿条数据操作时,缓存设置为100000条/Buffer,这对于这个级别的数据量是可行的

    2.2数据分类

       为了减少数据的冗余, 防止存储异常, 提高处理速度, 在开发过程中, 针对各类管理对象都进行编号处理, 并保存在不同的“对象定义表”中,即建立视图(VIEW)。视图中的数据来源于基表,对海量数据的处理,可以将数据按一定的规则分散到各个基表中,查询或处理过程中可以基于视图进行,这样分散了磁盘I/O。同类对象放在同一个定义表中, 编号不重复, 并用不同的字段定义管理对象的属性。记录和加工业务数据时, 只处理对象编号和业务数据, 把结果放在不同的“业务数据表”中。在进行数据检索和存取时, 通过数据视图或直接进行“对象定义表”和“业务数据表”的联接。根据业务数据被加工汇总的程度, 又进一步把“业务数据表”划分为不同的“原始业务数据表”、“按日汇总业务数据表”、“按月汇总业务数据表”。经过记录和加工的业务数据, 有部分是用来指导和规范业务活动的, 把这部分数据分别存放在不同的“业务管理表”中。数据分类结构如图1 所示。

     

                                                                    Flag1

    2.3数据分割

    海量数据处理难因为数据量大,那么解决海量数据处理难的问题其中一个技巧是减少数据量。可以对海量数据分批处理,然后处理后的数据再进行合并操作,这样逐个击破,有利于小数据量的处理,不至于面对大数据量带来的问题在使用系统过程中。临时表的使用和中间使用也是如此,如果对于超海量的数据,大表处理不了,只能拆分为多个小表。

    在具体的项目中,用户最关心的数据是当月的业务数据, 其次是当年的业务数据, 再次是往年的业务数据。查询业务数据的频率从高到低排列, 依次为当月、当年、往年, 而且查询的时间段极少跨年度。根据这个规律, 在数据库设计中, 把“业务数据表”按年度分割存放, 每年的“业务数据表”放在一个数据库(“年度数据库”)中, 同时对当月的“业务数据表”另外放在一个数据库(“当前数据库”)中, 这就保证了每个数据库和每个表的内容不会无限增长。“对象定义表”中的各个字段值具有相对稳定的特点, 因此也把它们按年度来保存。每个“年度数据库”中保存一份对应的“对象定义表”,当年的“对象定义表”保存在“当前数据库”中。“业务管理表”存放的是一些规则和规律, 数据量不大, 但是要求被查询时能迅速返回结果, 而且这些规则和规律只对正在发生和将来发生的业务起作用, 因此把它们放在“当前数据库”中。数据分割存放结构如图2 所示。

     

                                                               Flag2

    2.4数据处理算法

    对海量的数据处理,对大表建立索引是必行的,建立索引要考虑到具体情况,例如针对大表的分组、排序等字段,都要建立相应索引,一般还可以建立复合索引,对经常插入的表则建立索引时要小心,笔者在处理数据时,曾经在一个ETL 流程中,当插入表时,首先删除索引,然后插入完毕,建立索引,并实施聚合操作,聚合完成后,再次插入前还是删除索引,所以索引要用到好的时机,索引的填充因子和聚集、非聚集索引都要考虑。索引的优点和局限索引可以提高查询的效率,但会降低DML操作的效率。所以建立索引时需要权衡。对于DML操作比较频繁的表,索引的个数不宜太多;不同值较多的列上可建立检索,不同值少的列上则不要建。比如在用户表的“性别”列上只有“男”与“女”两个不同值,因此就没必要建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度[7]。

    必要时我们还可以给数据表创建“ 索引表”。例如,当需要进行模糊查询的时候,我们一般采取的解决办法是执行sql语句like select * from table where 某列 like‘ %×××%’,这样如前所述,即便该列已经加了索引,在进行like 查询时候,索引也起不到任何作用。那么,这种情况,应该怎么处理呢?

    我们以搜寻用户账户数据为例,假设一个表中存有一百万条数据,那么我们可以设计这个表有一个pk_id 列(长整型)来唯一标识一条记录。表中存在一列是描述信息列。该列的内容都是英文字母。这样,我们通过程序,先将该月数据进行处理,创建26 套索引表,每个索引表有两个列,一列(sKey)存放关键字,一列(sID)存放这些关键字在数据主表中出现的那些记录的pk_id(以某一特定分隔符来分割表示。例如 第 1、3、5 这3 条记录中存在关键字“TOY”那么在 T 索引表中有这样一条记录,TOY1,3,5)。这样,如果程序要搜索关键字是“TOY”的信息记录。执行过程是这样的:首先从T 索引表中,用“Select top 1 sID from T 索引表 where sKey =’TOY’” , 然后得到主数据表中的pk_id 为 1、3 、5 这三条记录 是含有关键字“TOY”的记录。这时,再执行“ select * from mainData where pk_id in(1,3,5)”, 得到所需数据。经过实际测试,用上述方法,比直接采用“select * from mainData where 描述信息列 like‘ %TOY%’”方式,系统返回结果的时间要快十倍以上,特别是在单表数据量超过百万后,效果更佳突出。

    又如在实际的数据访问中, 作业层工作人员最关注原始数据和流水清单数据, 而管理层和决策层人员最关注按日或按月汇总的业务数据报表。大部分用于管理和指导的数据也是要求按日或按月汇总。因此, 很多数据不是需要使用时才从原始数据来直接汇总加工, 而是可以采用“以空间换时间”的原则,在适当的时间, 事先进行数据的按日或按月汇总, 生成对应的汇总数据表。利用这种规律, 在受理作业层工作人员对原始数据和流水清单的要求时, 可以直接从“原始业务数据表”中访问检索; 同时, 在受理管理层和决策层人员的业务数据报表要求时, 避免了对大量原始数据的直接访问检索和加工汇总, 可以针对性地从“按日汇总业务数据表”或“按月汇总业务数据表”中的少量数据中检索汇总, 这样大大地提高了系统响应的速度和效率。

    具体的数据处理算法如下: (1) 每天新增的管理对象和对管理对象的修改直接保存在“当前数据库”的各个“对象定义表”中。(2) 在每日规定的结算时间或业务活动结束后, 进行每日数据结算。对原始业务数据进行加工整理, 生成各类按日汇总业务数据, 保存在“当前数据库”的各个“按日汇总业务数据表”中, 同时更新“业务管理表”。(3) 在每月月底的月报截止日, 进行月份数据结算和转存。把当月的“业务数据表”分类汇总, 生成按月汇总业务数据, 保存在“当年数据库”的各个“按月汇总业务数据表”中。(4) 把“当前数据库”中的各个“按日汇总业务数据表”转存到“当年数据库”的对应“按日汇总业务数据表”中, 并且清空“当前数据库”中的各个“按日汇总业务数据表”。(5) 在每年年底, 进行年度数据转存。把“当前数据库”中的各个“对象定义表”复制一份到“当年数据库”中, 生成新一年的数据库表结构。(6)将“当前数据库”作为新一年的“当月数据库”,删除“对象定义表”中已经淘汰的管理对象, 整理“业务管理表”[8][9][10]。

    2.5数据访问

    因数据是按年度存放的, 在访问数据时, 为使处理简单, 约定访问的时间段范围不能跨年度。这样在访问数据前, 首先判断要访问哪类数据。若为管理数据, 则直接从当月数据库中的“对象定义表”和“业务管理表”中查找。若为定义数据或业务数据, 则调用一个公用存储过程, 输入参数为访问时间段的起始日期和截止日期, 返回“对象定义表”和“业务数据表”所在的数据库名( 若访问时间段正好跨当年当月和当年往月时, 则要另外返回一标记说明业务数据跨数据库) 。而后, 在指定的数据库中访问对应的数据表。在对海量数据进行查询处理过程中,查询的SQL 语句的性能对查询效率的影响是非常大的,编写高效优良的SQL 脚本和存储过程是数据库工作人员的职责,也是检验数据库工作人员水平的一个标准,在对SQL 语句的编写过程中,例如减少关联,少用或不用游标,设计好高效的数据库表结构等都十分必要。

    2.6 加大虚拟内存

    如果系统资源有限,内存提示不足,则可以靠增加虚拟内存来解决。具体设置是,在[我的电脑]图标里点[右键]-[属性]弹出来的窗口里点[高级]选项卡,显示的第一项(性能)点[设置]在弹出来的窗口里点[高级]选项卡,显示内容的最下面(虚拟内存)点更改,然后在弹出的窗口里按需要改就好了,选择相应的分区选自定义大小输入后点右边的[设置],最后点[确定]并重启,设置完成。比如,在实际项目中遇到针对18 亿条的数据进行处理,当主机内存仅为为1GB,1 个P4 2.4G 的CPU,对这么大的数据量进行聚合操作肯定是有问题的。如果采用了加大虚拟内存的方法,在6块磁盘分区上分别建立了6个4096M 的磁盘分区,用于虚拟内存,这样虚拟的内存则增加为4096*6+1024=25600M,很好的解决了数据处理中的内存不足问题。

    2.7使用文本格式进行处理

    对一般的数据处理可以使用数据库,如果对复杂的数据处理,必须借助程序,那么在程序操作数据库和程序操作文本之间选择,是一定要选择程序操作文本的,原因为:程序操作文本速度快;对文本进行处理不容易出错;文本的存储不受限制等。例如一般的海量的网络日志都是文本格式或者csv 格式(文本格式),对它进行处理牵扯到数据清洗,是要利用程序进行处理的,而不建议导入数据库再做清洗[11]。

     

    3.结束语

     

        本文通过分析网络支付业务的海量数据带来的问题,通过改进和优化数据库配置、数据分割、数据分类、处理算法、数据访问、虚拟内存和文本格式处理等方面,对网络支付带来的海量数据存取处理进行研究,提出了几个可行性的解决方案。该方案在实际系统中发挥了重要作用,具有实际指导作用。

     

     

    参  考  文  献

     

    [1]易观国际[EB/OL].2011[2011-11-8]. http://www.199it.com/archives/18036.html

    [2]别坤.网络支付的技术演进[J].互联网周刊.2011,(02):40-41.

    [3]Baidu baike[EB/OL].2010[2010-6-13]. http://baike.baidu.com/view/157458.html.

    [4]何芳原.浅谈海量数据处理技术研究[J].硅谷.2009(08):59-60

    [5]张金乙,姜文志,蒋伟俊,等.高速海量数据的接收和存储系统的设计与实现[J].计算机时代. 2007( 12):67-68.

    [6]戴子良.海量数据处理分析[J] . Windows IT Pro Magazine. 2007(1): 37-39.

    [7]李向阳,李朝庆.海量数据处理的几个技术问题及其解决方案[J].保险职业学院学报.2005(05):51-52 

    [8]张占杰.浅谈海量数据处理技巧[J]科技传播. 2011(02):170-171

    [9][韩]李华植.海量数据库解决方案[M].郑保卫,盖国强译,京:电子工业出版社.2011

    [10]周喜.Oracle外部过程在高性能海量数据处理中的应用[J].福建电脑2008(05):91-92

    [11]林茂.虚拟现实项目中海量数据处理方法分析[J].价值工程.2011(19):158-159

     

     (转载请注明出处)

    展开全文
  • 本博客来自我的新书Java性能优化(暂定名),第5章的Java代码优化技巧节选2,也欢迎阅读我的新书 ...使用EnumMap来存取Key是Enum的,会有较快的速度,如下是一个网关返回对象Result的的状态属性,是一个枚举类 ...

    本博客来自我的新书Java性能优化(暂定名),第5章的Java代码优化技巧节选2,也欢迎阅读我的新书 《Spring Boot 2 精髓 》

    5.2 高速Map存取

    使用EnumMap来存取Key是Enum的,会有较快的速度,如下是一个网关返回对象Result的的状态属性,是一个枚举类

        public static  enum Status {
          SUCCESS(1,"成功"),FAIL(2,"处理失败"),DEGRADE(98,"成功降级"),UNKOWN(99,"未知异常");
    
          private int code;
          String msg;
          Status(int code,String msg){
            this.code = code;
            this.msg = msg;
          }
    
          public int getCode() {
            return code;
          }
    
          public String getMsg() {
            return msg;
          }
        }
    

    考虑到定义微服务网关返回对象,应该尽量使用java自带类型,以避免各种序列化,反序列化问题,网关不返回此枚举值,而是返回msg字段,因此可以构造一个EnumMap,Key为Status枚举类型,Value为Status.msg 属性

        Map<Status,String> enumMap =null;
        private void initEnumMap(){
          enumMap = new EnumMap<Status,String>(Status.class);
          for(Status status:Status.values()) {
            enumMap.put(status,status.msg);
          }
        }
    

    构造EnumMap的时候,内部实际上通过一个数组保存了所有的枚举值,索引是枚举的ordinal得到 当要根据Enum来操作EnumMap,只需要先调用ordinal,得到其索引,然后直接操作数组即可。操作一维数组有这最快的速度

    有些场景下Key是int类型,这时候可以参考第二章的IntMap

    有很多Key-Value使用场景,都可以转化为根据索引对数组的存取,我们学过的C语言,操作的是变量名,但实际上还是根据指针获取到内存中的值,Beetl模板语言,对变量的访问,也不像其他脚本语言那样,通过变量名访问Map获取其值,而是在编译期间就为这个变量分配好了索引值,所有变量都保存在一个一维数组里,这样的存取,相比于Map存取,有十倍以上性能提高。

    如下一段脚本语言

        var a = 1;
        var b = 2+a;
    

    有些语言引擎会翻译成类似如下java代码

        context.put("a",1);
        context.put("b",context.get("a")+2);
    

    这里context是一个Map。从Map里通过Key存取尽管很快,但是Beetl还是在解析脚本语言的时候给变量设置了数组所在索引,因此如上脚本在Beetl中翻译如下

        Object[] vars = context.vars;
        vars[0] =1 ;
        vars[1] = vars[0]+2
    

    这里为变量a,b 分别设置了在变量表中的索引是0和1;

    曾优化过一个电商的基础组件,电商系统每天调用这个组件的次数高达10+万亿次,这个组件是用来统计方法调用的时长,收集一段时间后,定期发送到 分析系统,用于查找和分析方法的性能,其中有一部分代码是记录以调用时长分类,记录条用次数,下面的代码

        Watch watch = Watch.instance("orderByWx"); //初始化,从微信来的订单
        //调用其他业务逻辑.....
        Profile.add(watch.endWatch());//记录一次
    

    Watch类定义如下

        public class Watch {
          String key;
          long start;
          long millis =-1;
          private Watch(String key){
            this.key = key;
            this.start = System.nanoTime();
          }
          public static Watch instance(String key){
            return new Watch(key);
          }
    
          public Watch endWatch(){
            millis = millisConsume();
            return this;
          }
    
          /**
           * 返回方法调用消耗的毫秒
           * [@return](https://my.oschina.net/u/556800)
           */
            private long millisConsume(){
              return  TimeUnit.NANOSECONDS.toMillis(System.nanoTime()-start);
            }
    
        }
    

    Watch的key属性记录调用类型,如订单调用,商品查询信息等,可以为任意值,start属性记录了调用时候的时间点,millis会在调用endWatch后记录调用消耗的毫秒数。

    Profile类用来记录监控信息,并通过其他后台线程发送到性能分析中心,例子做了一定简化,只呈现保存部分

        public class Profile {
          //调用时长和调用次数
          static Map<Integer, AtomicInteger> countMap = new ConcurrentHashMap<>();
          /**
           * 对调用时间计数
           * [@param](https://my.oschina.net/u/2303379) watch
           */
          public static void addWatch(Watch watch){
            int consumeTime = (int)watch.millis;
            AtomicInteger  count  = countMap.get(consumeTime);
            if(count==null){
              count = new AtomicInteger();
              AtomicInteger old  = countMap.putIfAbsent(consumeTime,count);
              if(old!=null){
                count = old;
              }
            }
            count.incrementAndGet();
          }
        }
    

    Profile会初始化一个ConcurrentHashMap用于计数,Key为Integer类型,表示调用时长,Value为AtomicInteger,用来计数,每次调用,都会自增一个

    Profile性能有一点优化空间,如果从业务角度考虑,大部分需要监控的方法或者代码块,执行时间并不长,假设不超过32毫秒(这是一个假设值,根据系统运维统计分析后得出),因此,可以考虑用一个32长度的数组来存放32毫秒以内的所有计数,超过32毫秒的再沿用以前的方法

        static Map<Integer, AtomicInteger> countMap = new ConcurrentHashMap<>();
        static final int MAX  = 32;
        //保存消耗时间为32毫秒的调用次数
        static AtomicInteger[] counts = new AtomicInteger[MAX];
        static{
            for(int i=0;i<MAX;i++){
                counts[i] = new  AtomicInteger();
            }
        }
    
        /**
        * 对调用时间计数
        * [@param](https://my.oschina.net/u/2303379) watch
        */
        public static void addWatch(Watch watch){
            int consumeTime = (int)watch.millis;
            if(consumeTime<MAX){
                counts[consumeTime].incrementAndGet();
                return ;
            }
            AtomicInteger  count  = countMap.get(consumeTime);
            //原有的Profile.addWatch逻辑,在此忽略
    
        }
    

    新完善的代码使用counts数组记录32毫秒以内调用计数,因此当addWatch被调用的时候,先判断millis是否小于32毫秒,如果是,直接用数组获取计数器,然后自增。否则,沿用以前的逻辑

    优化后,通过JMH测试(com.ibeetl.code.ch05.WatchTest),性能略有提升,如下输出:

        Benchmark                     Mode  Samples      Score  Score error   Units
        c.i.c.c.WatchTest.better     thrpt       20  16447.171     2195.344  ops/ms
        c.i.c.c.WatchTest.general    thrpt       20  11566.545      601.579  ops/ms
    

    性能优化提高了40%,尽管看着不如本书其他例子性能提升那么明显,但考虑这是一个基础工具,性能提升会对所有系统都有帮助,实际上,作者优化为跟此性能监控工具后,对业务系统的有提升5%的性能提升,在拥有数十万台服务器的大型电商系统,这个系统提升还是有意义的。

    转载于:https://my.oschina.net/xiandafu/blog/3069785

    展开全文
  • 数据库海量数据存取优化

    千次阅读 2011-03-17 16:27:00
    数据库海量数据存取优化>>[相关实例说明] 版权说明: /* 作者:D-EEtl Aiset Seidel 时间:2008-09-11 网站:http://blog.csdn.net/InfoNST/<br />团队:Information Network ...

    数据库海量数据存取优化>>[相关实例说明]

    版权说明:

    /*

    作者:D-EEtl Aiset Seidel

    时间:2008-09-11

    网站:http://blog.csdn.net/InfoNST/

    团队:Information Network Security Technology

                 信息网络安全技术

                 Info.InfoNST.CoM

    */

     

    一、数据量过大,数据中什么情况都可能存在。

    如果说有10条数据,那么大不了每条去逐一检查,人为处理,如果有上百条数据,也可以考虑,如果数据上到千万级别,甚至过亿,那不是手工能解决的了,必须通过工具或者程序进行处理,尤其海量的数据中,什么情况都可能存在,例如,数据中某处格式出了问题,尤其在程序处理时,前面还能正常处理,突然到了某个地方问题出现了,程序终止了。

     

    二、软硬件要求高,系统资源占用率高。

    对海量的数据进行处理,除了好的方法,最重要的就是合理使用工具,合理分配系统资源。一般情况,如果处理的数据过TB级,小型机是要考虑的,普通的机子如果有好的方法可以考虑,不过也必须加大CPU和内存,就象面对着千军万马,光有勇气没有一兵一卒是很难取胜的。

     

    三、要求很高的处理方法和技巧。

    这也是本文的写作目的所在,好的处理方法是一位工程师长期工作经验的积累,也是个人的经验的总结。没有通用的处理方法,但有通用的原理和规则。

     

    下面我们来详细介绍一下处理海量数据的经验和技巧:

     

    一、选用优秀的数据库工具

    现在的数据库工具厂家比较多,对海量数据的处理对所使用的数据库工具要求比较高,一般使用Oracle或者DB2,微软公司最近发布的SQL Server 2005性能也不错。另外在BI领域:数据库,数据仓库,多维数据库,数据挖掘等相关工具也要进行选择,象好的ETL工具和好的OLAP工具都十分必要,例如Informatic,Eassbase等。笔者在实际数据分析项目中,对每天6000万条的日志数据进行处理,使用SQL Server 2000需要花费6小时,而使用SQL Server 2005则只需要花费3小时。

     

    二、编写优良的程序代码

    处理数据离不开优秀的程序代码,尤其在进行复杂数据处理时,必须使用程序。好的程序代码对数据的处理至关重要,这不仅仅是数据处理准确度的问题,更是数据处理效率的问题。良好的程序代码应该包含好的算法,包含好的处理流程,包含好的效率,包含好的异常处理机制等。

     

    三、对海量数据进行分区操作

    对海量数据进行分区操作十分必要,例如针对按年份存取的数据,我们可以按年进行分区,不同的数据库有不同的分区方式,不过处理机制大体相同。例如SQL Server的数据库分区是将不同的数据存于不同的文件组下,而不同的文件组存于不同的磁盘分区下,这样将数据分散开,减小磁盘I/O,减小了系统负荷,而且还可以将日志,索引等放于不同的分区下。

     

    四、建立广泛的索引

    对海量的数据处理,对大表建立索引是必行的,建立索引要考虑到具体情况,例如针对大表的分组、排序等字段,都要建立相应索引,一般还可以建立复合索引,对经常插入的表则建立索引时要小心,笔者在处理数据时,曾经在一个ETL流程中,当插入表时,首先删除索引,然后插入完毕,建立索引,并实施聚合操作,聚合完成后,再次插入前还是删除索引,所以索引要用到好的时机,索引的填充因子和聚集、非聚集索引都要考虑。

     

    五、建立缓存机制

    当数据量增加时,一般的处理工具都要考虑到缓存问题。缓存大小设置的好差也关系到数据处理的成败,例如,笔者在处理2亿条数据聚合操作时,缓存设置为100000条/Buffer,这对于这个级别的数据量是可行的。

     

    六、加大虚拟内存

    如果系统资源有限,内存提示不足,则可以靠增加虚拟内存来解决。笔者在实际项目中曾经遇到针对18亿条的数据进行处理,内存为1GB,1个P4 2.4G的CPU,对这么大的数据量进行聚合操作是有问题的,提示内存不足,那么采用了加大虚拟内存的方法来解决,在6块磁盘分区上分别建立了6个4096M的磁盘分区,用于虚拟内存,这样虚拟的内存则增加为 4096*6 + 1024 = 25600 M,解决了数据处理中的内存不足问题。

     

    七、分批处理

    海量数据处理难因为数据量大,那么解决海量数据处理难的问题其中一个技巧是减少数据量。可以对海量数据分批处理,然后处理后的数据再进行合并操作,这样逐个击破,有利于小数据量的处理,不至于面对大数据量带来的问题,不过这种方法也要因时因势进行,如果不允许拆分数据,还需要另想办法。不过一般的数据按天、按月、按年等存储的,都可以采用先分后合的方法,对数据进行分开处理。

     

    八、使用临时表和中间表

    数据量增加时,处理中要考虑提前汇总。这样做的目的是化整为零,大表变小表,分块处理完成后,再利用一定的规则进行合并,处理过程中的临时表的使用和中间结果的保存都非常重要,如果对于超海量的数据,大表处理不了,只能拆分为多个小表。如果处理过程中需要多步汇总操作,可按汇总步骤一步步来,不要一条语句完成,一口气吃掉一个胖子。

     

    九、优化查询SQL语句

    在对海量数据进行查询处理过程中,查询的SQL语句的性能对查询效率的影响是非常大的,编写高效优良的SQL脚本和存储过程是数据库工作人员的职责,也是检验数据库工作人员水平的一个标准,在对SQL语句的编写过程中,例如减少关联,少用或不用游标,设计好高效的数据库表结构等都十分必要。笔者在工作中试着对1亿行的数据使用游标,运行3个小时没有出结果,这是一定要改用程序处理了。

     

    十、使用文本格式进行处理

    对一般的数据处理可以使用数据库,如果对复杂的数据处理,必须借助程序,那么在程序操作数据库和程序操作文本之间选择,是一定要选择程序操作文本的,原因为:程序操作文本速度快;对文本进行处理不容易出错;文本的存储不受限制等。例如一般的海量的网络日志都是文本格式或者csv格式(文本格式),对它进行处理牵扯到数据清洗,是要利用程序进行处理的,而不建议导入数据库再做清洗。

     

    十一、定制强大的清洗规则和出错处理机制

    海量数据中存在着不一致性,极有可能出现某处的瑕疵。例如,同样的数据中的时间字段,有的可能为非标准的时间,出现的原因可能为应用程序的错误,系统的错误等,这是在进行数据处理时,必须制定强大的数据清洗规则和出错处理机制。

     

    十二、建立视图或者物化视图

    视图中的数据来源于基表,对海量数据的处理,可以将数据按一定的规则分散到各个基表中,查询或处理过程中可以基于视图进行,这样分散了磁盘I/O,正如10根绳子吊着一根柱子和一根吊着一根柱子的区别。

     

    十三、避免使用32位机子(极端情况)

    目前的计算机很多都是32位的,那么编写的程序对内存的需要便受限制,而很多的海量数据处理是必须大量消耗内存的,这便要求更好性能的机子,其中对位数的限制也十分重要。

     

    十四、考虑操作系统问题

    海量数据处理过程中,除了对数据库,处理程序等要求比较高以外,对操作系统的要求也放到了重要的位置,一般是必须使用服务器的,而且对系统的安全性和稳定性等要求也比较高。尤其对操作系统自身的缓存机制,临时空间的处理等问题都需要综合考虑。

     

    十五、使用数据仓库和多维数据库存储

    数据量加大是一定要考虑OLAP的,传统的报表可能5、6个小时出来结果,而基于Cube的查询可能只需要几分钟,因此处理海量数据的利器是OLAP多维分析,即建立数据仓库,建立多维数据集,基于多维数据集进行报表展现和数据挖掘等。

     

    十六、使用采样数据,进行数据挖掘

    基于海量数据的数据挖掘正在逐步兴起,面对着超海量的数据,一般的挖掘软件或算法往往采用数据抽样的方式进行处理,这样的误差不会很高,大大提高了处理效率和处理的成功率。一般采样时要注意数据的完整性和,防止过大的偏差。笔者曾经对1亿2千万行的表数据进行采样,抽取出400万行,经测试软件测试处理的误差为千分之五,客户可以接受。

     

    还有一些方法,需要在不同的情况和场合下运用,例如使用代理键等操作,这样的好处是加快了聚合时间,因为对数值型的聚合比对字符型的聚合快得多。类似的情况需要针对不同的需求进行处理。

     

    海量数据是发展趋势,对数据分析和挖掘也越来越重要,从海量数据中提取有用信息重要而紧迫,这便要求处理要准确,精度要高,而且处理时间要短,得到有价值信息要快,所以,对海量数据的研究很有前途,也很值得进行广泛深入的研究。

     

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/InfoNST/archive/2008/09/11/2913251.aspx

    展开全文
  • Redis 在大量数据中的存取

    千次阅读 2020-03-30 17:27:29
    以前在公司的时候遇到了一个需求,要求将原本存储在结构化数据库中的数据部分使用Redis进行存取,用来提高服务的响应速度。 而且还要求后端模块中的更新要有新旧两份,大意就是说当用户请求这部分数据的时候,若这...

    以前在公司的时候遇到了一个需求,要求将原本存储在结构化数据库中的数据部分使用Redis进行存取,用来提高服务的响应速度。

     而且还要求后端模块中的更新要有新旧两份,大意就是说当用户请求这部分数据的时候,若这部分数据正在更新,那么数据库应该返回旧版本的数据以保证服务能正常进行。当新数据更新完毕的时候,下一次用户请求的时候就是新数据。

    因为Redis中是k-v形式,hash存储,所以当时的设计就是根据 模块名-表名-新/旧标识符-字段名 来作为key的前缀,在数据库存储新旧两份数据,启动的时候通过初始化确定当前使用的前缀,当更新的时候,使用新前缀插入数据,当插入结束后切换用户访问表名。(当然很可能会出现用户两次请求的数据会不一样,或者前后读取的数据一部分是新数据一部分是旧数据,导致计算结果错误)

    这其中就遇到了一个问题,Redis大数据的存取,因为业务数据有数十万条,所以普通的存取方法会导致阻塞。

    redis中的存原本是使用nodejs,使用set命令进行存的,但是后来发现有个更好的方法。

    使用redis客户端的pipeline 。具体的可以看一下这个->https://www.cnblogs.com/huangxincheng/p/6212406.html

    读取的时候也不可以使用 key * 来进行匹配前缀,因为这样会有很多的数据一起发回来,会造成阻塞。Redis提供了scan命令来解决这个问题。命令如:

    scan (返回值) match (匹配前缀/形式) count (一次返回的记录条数)

    然后通过迭代获取所有数据

    展开全文
  • 开放存取知识库及其数据采集规范的研究猛1,张永锋2,李振华2,霍东云3,赵弋洋4,王莲41教育部科技发展中心,北京 1000802清华大学软件学院,北京 1000843...
  • 如何处理几十万条并发数据?

    千次阅读 2008-11-11 18:27:00
    数据并发: 使用存储过程+web ervice 实现异步存取好一些,不过要设计好,要不然就经常死锁哈,这样可以快速的缓冲数据(因为几十万的并发数据一般都是比较大型的了,所以服务器是少不了的哈,所以就不要担心计算机...
  • 1)从磁盘驱动器读取一个字的时间开销比从主存中读取的开销大1000倍。 2)从寄存器读数据比从主存中读取要快100倍。 3)从处理器芯片上的L1高速缓存读数据的速度和访问寄存器文件几乎一样快。(L1高速缓存容量可达...
  • 在 RH9 下存取 Windows 下的共享文件夹

    千次阅读 2010-07-20 00:19:00
    Linux 与 Windows 通过 samba 协议进行文件夹的共享。在 Linux 下安装 samba 软件包和开启 samba 服务后,通过配置 samba 的配置文件,可以开启 Linux 下的共享资源。... 在 Windows 下存取 Linux 的共
  • 所谓“存取键”就像 windows 应用程序中的 Alt 快捷键,同时按 Alt 键和某个字母键,可以快速切换到文本框、按钮等页面对象上。(1)、文本框的 Access Key:"Namebox" ACCESSKEY="N">Name:"TEXT" ID="Namebox" SIZE=...
  • 采用这种方法时,可实现对结点的随机存取,即每一个结点对应一个序号,由该序号可以直接计算出来结点的存储地址。但顺序存储方法的主要缺点是不便于修改,对结点的插入、删除运算时,可能要移动一系列的结点。 优点...
  • 最近几天大数据量的处理,不知道是使用List还是Map好,在网上看了好多,看到最多的说是使用Map,但是最后我还是决定写了一个测试类,来看看他们之间速度的快慢。 ... import java.util.*; public class Main { ...
  • android查询几十万条数据的调研(一)

    千次阅读 2016-05-16 16:10:19
    此次调研分两步走吧, 先从测试的角度看(一), 再从源码的角度看(二)(待续).
  • Asp.Net(C#)+Sql Server三层架构下数据存取方案 引言:参与了一个大型社区程序的开发,现在将相关开发经验陆续总结出来,...一般小数量的程序不会有问题,但数据以十万百万条计的时候,数据库的吞吐量的限制就会表现的
  • 数据库海量数据存取优化>>[相关实例说明]版权说明:/*作者:D-EEtl Aiset Seidel时间:2008-09-11网站:http://blog.csdn.net/InfoNST/团队:Information Network Security Technology 信息网络安全技术 Info....
  • caffeine底层是用ConcurrentHashMap来进行的数据存储,大家都知道HashMap扩容的事,扩容2倍,就要进行一次copy,里面动辄几十万个key,扩容resize时,cpu会占用比较大。尤其是cpu本身负荷很重时,这一步也会卡住。 ...
  • 3、通过 Hash 函数把数据按照关键字 key 映射到数组中的某一个位置,并在此数据上进行数据存取 结论:无论是 array(1, 2, 3) 还是array(1 => 2, 2=> 4)等,本质上都是key=>value形式, array(1, 2, 3),实际上是 ...
  • 引言: 参与了一个大型社区程序的开发,现在将相关开发...一般小数量的程序不会有问题,但数据以十万百万条计的时候,数据库的吞吐量的限制就会表现的比较明显。这里的解决方案其实也就是把海量数据信息分成一条条取
  • 淘宝技术这年——光棍节的狂欢

    千次阅读 2013-05-17 13:30:04
    淘宝技术这年——光棍节的狂欢  淘宝网不就是一个网站吗?是的,但淘宝网不是一个简单的网站,它的规模排在全球前几名,顶尖的网站需要顶尖的技术作为支撑。在用户享受淘宝的乐趣的背后,有哪些神秘的技术在...
  • 《淘宝技术这年》

    千次阅读 2017-11-10 10:14:25
    《淘宝技术这年》
  • 月百度,阿里巴巴,迅雷搜狗最新面试七题(第201-270题)引言 当即早已进入10月份,十一过后,招聘,笔试,面试,求职渐趋火热。而在这一系列过程背后浮出的各大IT公司的笔试/面试题则蕴含着诸多思想与设计,...
  • 本文是我最近读书笔记的一篇文章,主要是阅读《淘宝技术这年》的第一部分,主要包括淘宝网的技术流程和基础介绍,希望文章对大家有所帮助,同时记录自己最近学习的内容。我似乎是2007年初中看《赢在中国》的时候...
  • 搭建Mycat+Zookeeper+HAProxy+Keepalived+MySQL高可用架构实现亿级数据存储!!
  • (考试时间为 120 分钟,满分为 100 分) ... (“十万个为什么”电脑学习网)  其他网站: http://sogo99.com  (“搜狗99”网络门户)   http://neteye.blogchina.com  (“网眼”博客中国)  2004.12.30
  • 程序员的年工作创业经历

    千次阅读 2020-08-08 09:54:43
    吉日噶拉(在外企、上市公司工作过,自己也创业失败过,遇到过很多失败挫折,甚至露宿街头,但是最后还是挺过来了),是一个几年的程序员了,本文介绍了他的相关经历,以及他的一些经验,无论是对刚入门的程序员,...
  • C#OOP之四 .Net Framework简介

    千次阅读 2016-05-01 08:03:23
    FCL类库大约有7000多个类(每个类可能会有上百个方法或属性,比当初18000多个Win32 API显得更厉害了),别看多,理清思路与脉络、法归一,学习不是难事。 言归正传,这些类被按照命名空间进行了分别别类(命名...
  • Hadoop年解读与发展预测

    千次阅读 2016-06-24 16:34:42
    Hadoop年解读与发展预测 摘自 http://www.infoq.com/cn/articles/hadoop-ten-years-interpretation-and-development-forecast 编者按:Hadoop于2006年1月28日诞生,至今已有10年,它改变了企业对数据的...
  • 感动于技术的日新月异时,希望通过这篇内容深入解读Hadoop的昨天、今天和明天,憧憬下一个年。 本文分为技术篇、产业篇、应用篇、展望篇四部分  技术篇    2006年项目成立的一开始,
  • 原文地址:...本文介绍了他的相关经历,以及他的一些经验,无论是对刚入门的程序员,还是工作了年八年的程序员都有一些经验值得借鉴学习。(一)三年前的一个项...
  • 年了,Hadoop的前世今生

    千次阅读 2016-11-18 17:22:09
    运行了世界上最大的Hadoop应用,宣布其搜索引擎产品部署在一个拥有1个内核的Hadoop集群上。 2008年4月,在900个节点上运行1TB排序测试集仅需209秒,成为世界最快。 2008年6月,Hadoop的第一个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,826
精华内容 6,330
关键字:

存取十万