数据蒋堂

其他

怎样让国产芯片性能超越Intel

做一次标题党,其实我们做软件的当然没办法改变芯片的性能,也不可能真地让国产芯片超越Intel。这个话题从去年做过的一次性能测试说起,先看测试结果:这些题目原本是某大用户在选型数据库时用于评测性能的。给定了数据(结构和规模)和SQL,在同样的硬件环境下让各家数据库都跑一下,看谁的速度最快。我们从中选择了几个耗时最长的SQL,再做了少量补充。然后准备了两组集群,一组用Intel芯片,另一组用国产飞腾芯片,安装好分布式数据库和集算器,并在数据库中生成测试数据。1.用SQL在数据库中执行,记录时长;2.将SQL改写成SPL(这有些工作量,涉及到算法更改),但仍读取数据库中数据计算,记录时长;3.将数据导出到文件,使用集算器特有的组表格式存储,再改写SPL(更换数据源,使用组表数据源会比使用数据库源更简单)计算,记录时长;然后就得到了上面那个测试结果表。还有几点说明:1.我们刻意选择了一些在原评测中耗时最长的SQL(几乎都>1小时),所以这里看到的数据库上跑SQL的性能都较差;原测试中也有几条能跑得很快的SQL,但这里没有选用。2.原评测中要求只要返回第一批数据即可,不需要返回全部结果集,这里延用了此规则,但我们补充了一些题目,在其中确保必须把涉及数据全部遍历到才可能计算出结果(比如增加GROUP
2019年2月20日
其他

中国报表漫谈

按:在敏捷BI横行的年代,报表这个概念也有了更大的外延,很多用户甚至技术人员都会将由复杂格式报表与BI系统中拖拽出来的报表混为一谈。这是一篇2004年底写的老文,现在重读,对于理解复杂报表仍有意义,不过对于相关工具的评说确实有些过时了,但也不做修改了,简单修订一下重发这两年来雨后春笋般地冒出二三十家做报表工具的公司,统统号称能处理中国式报表,大概是这中国报表复杂得都世界闻名了,但凡能搞得定中国的报表,那也就没什么搞不定的报表了。弄到后来有好些所谓的报表只要能在格子里摆条斜线就敢说能对付中国报表(这也太小瞧祖国文化了),而且老外也开始扬言适合于中国报表了,这时髦,不赶怕是不行了。可话说回来,这中国的报表确实够复杂、巨费劲。用户拿出一撂纸往咱面前一堆:“就照这个做吧”,立马头就晕了,随便选一张搞个两三天是家常便饭,运气坏了折腾一礼拜也不是多罕见的事,手里握着世界排名前三的高档武器(这里不方便点名批评,大家心领神会吧)依然搞得人垂头丧气,末了还是得拿出看家工夫——写代码!谁让咱是程序员呢,就这命呗。那到底啥才算是中国式报表?中国的报表到底复杂在哪里?号称能对付中国报表的工具到底灵不灵?中国人是不是吃错了什么药非要把报表搞这么费劲?我们就来胡乱聊聊中国报表的这些闲事。我们先来研究一下中国报表的特点和当前报表工具的问题。先从样子上看,中国人的报表好象很少有没有格线的,不仅有格线,还恨不得搞它三五层,大格套小格,更不要说大伙津津乐道的斜线了。可人家老外的报表真地很少有线哟,就那么几个数对得倒也整齐。不过,老外的表层数不多,不容易看花眼,中国的表头比较乱,没有格线容易看走眼的,所以格线确实是非常必要的。格线既然是为了令数据对齐的,那线本身更是应当横平竖直、一贯到底,小学生画表都是拿尺子比着,一气画老长一条。可老外的武器中却没顺便带上尺子,只是把一些数连同其框框摆来摆去,美其名曰拖拽,号称只要用鼠标简单拖拽就可画出报表。这么一来,一条长线就要靠十几个甚至几十个小框框拼出来了,一个挨一个。哎,本来一笔就画得出来的线,要堆上几十段,你说烦不烦?单层的还可说,偏偏我国人民喜欢一层套一层,这样就得上下左右全面对齐,这么多小框框指不定哪个不太老实偏出去一点点,直线就变阶梯,中国报表还经常特宽,搞得顾了左顾不了右,哪天用户心血来潮要加减几个框框,那可累死人了(用户反正不干活,眼不见心不烦),而且这种纯粹的机械劳动叫我等来搞,真有愧于国家多年的栽培,此时那三字经是不由得要脱口而出的。这还没算完,辛辛苦苦画整齐的表,怎么打印到纸上又不齐了,敢情这东西还和分辨率相关,哎,这打印机何苦要比屏幕分辨率高这许多。这种所谓先进的“拖拽式”其实可以用来画任何东西,是一个一般性的图元编辑器模型,半点也没有体现出表格的规律性,什么都能画,可什么画起来都不大方便。老外的不行,国人造的如何?可惜,绝大多数国货都在抄老外,谁叫人家发达呢,咱也分不清好不好,都给抄来了。难道就没什么可使的兵器了?有!当然有,光是摆样子又没多难,人家老外也有这种兵器,而且好使得很。那就是大名鼎鼎的EXCEL了。EXCEL采用网格线把格子围出来的画法,配合以合并格和边框,好比给大家配上了尺子,这下爽了,一个看似复杂的表格三下五除二就搞定了。EXCEL的画法充分体现了表格的规律性,所以特别方便,方便得连用户自己都会搞了。这下又坏事了,用户太喜欢EXCEL了,于是要求所有报表都要能生成EXCEL的格式,更有甚者,以后不再给咱一撂纸了,给咱一批EXCEL文件,扬言要咱直接读进去,省得再画。这可更苦了用老外工具(或抄老外的国货)的人,拖拽式和EXCEL的搞法完全不同,定要生成EXCEL文件的话,大都会丧失格式(国货大抵如此),个别使了大劲的可以搞得很象(老外的一般有这个本事),又还是依赖于您的对齐工夫,稍有不慎,嘿嘿,一行变N行。至于读入EXCEL文件,那更是想都别想,还不如打到纸上再对着描着舒坦呢。那咱干脆直接就用EXCEL好了,不用这些罗里巴索的工具了。哎,这还是有点不大行,EXCEL的格式上是顶呱呱没得说,可没什么数据汇总方案,基本上没法从数据库中读出数据自动产生报表,这毕竟是咱用报表工具的主要目的,否则又得编程序往格子里填数据。刚才说了,绝大多数国货在抄那种“拖拽式”的老外,那剩下的小部分就在抄EXCEL了,同样抄得倍儿象,没什么数据汇总功能,只能画画样子,也还是没法用。不过,也真有被这可恶的“拖拽式”折磨过头的,自已编程去准备数填入EXCEL(或类似产品)。这现象其实也还得怪这些报表工具不争气,不仅画起来费劲,统计汇总的本事也就比EXCEL强一点点,离中国报表的要求差得远。这就是我们要谈的第二个方面,也是中国报表真正最复杂的地方。堆框框虽费劲,可有道是只要功夫深,铁杵磨成针,但统计汇总本事不行的话那就没治了,无论功夫有多深,木杵总也磨不成针。数据统计方面的问题要比报表样式的问题多得多,也严重得多,要分几个方面来研讨。这些研讨主要且只能针对拖拽式的报表工具进行,毕竟这些东西还算有点自动化本事。中国报表统计方面第一个重要特征是多数据源。所谓多数据源是指同一张报表的数据会来自多个不同的数据表或视图,甚至来自多个不同的异构数据库!这东西空口说有点费劲,咱上俩例子。1)人员信息表
2018年12月11日
其他

内存数据集产生的隐性成本

当我们要对数据做一些非常规的复杂运算时,通常要将数据装入内存。现在也有不少程序设计语言提供了内存数据集对象及基本的运算方法,可以较方便地实现这类运算。不过,如果对内存数据集的工作原理了解不够,就可能写出低效的代码。我们看数据集的产生。比如要生成一个100行2列的数据集,第一列x为序号,第二列xx是第一列的平方。第一种方法,先生成一个空数据集,再一行一行地追加数据进去。AB1=create(x,xx)2for
2018年12月4日
其他

应对报表没完没了的五个步骤

报表的业务稳定性天生很差,业务开展过程中会催生出许多新的查询统计需求,这就造成了没完没了的报表,这是个无法被消灭的任务,也是许多行业软件开发商非常头疼的事情。投入了很多人力,也引入了专业报表工具以及敏捷BI产品,却依然搞得灰头土脸,常常被客户抱怨。这是为什么呢?又该怎么解决呢?因为报表工具只能解决报表呈现环节的那部分工作,而报表开发过程中,占据工作量更大的部分是在数据准备的环节,这就不是报表工具该负责的,当然也对此无能为力。而敏捷BI也只能解决一些非常规整的报表,而且也严重依赖于事先建设的数据集,瓶颈仍然是个数据准备任务。当前实现数据准备的主流技术,要么是数据库中用SQL编程,要么是应用程序中用高级语言编程,对于步骤较多的复杂数据准备来讲,开发起来都非常繁琐。实现周期长,就难以应对多变的需求;这些技术的掌握难度高,也就要求较高成本的高技术人员。说白了,报表开发复杂度高的技术原因主要并不在报表本身,而是数据。除了技术原因外,还有应用结构和团队管理方面的因素也会造成报表开发的成本居高不下。在许多应用系统中,报表是耦合在其中的一些功能,而业务系统的技术环境很复杂,这就迫使报表开发人员也要熟悉这些东西,也就很难把报表开发人员和业务系统的开发人员分开,业务系统上线之后,开发人员仍然要继续坚守开发报表,很难把这项工作转交给客户方的运维人员。开发过程中的有效沟通也会影响工作量。我们经常会发现这样的现象:业务人员提出报表需求,等技术人员做好后才发现某些概念术语的理解有误,统计口径不一致,结果并不是业务人员想要的,然后也只能重做,甚至反复多次才能正确实现,严重浪费开发资源。针对上面说的这些原因,我们提出五个步骤来解决。一.
2018年11月27日
其他

“后半”有序的分组

上一期我们说了前半有序的数据,这次我们来看看“后半”有序的情况。回顾一下前半有序的说法:我们要把数据集T按字段a,b排序时,如果T已经对a有序,则可以利用这一特点实现高性能算法。但后半有序却不是对称地把问题理解成T已经对b有序时要对a,b排序的任务,这个“后半”序信息并没有多大利用价值。这里说的“后半”有序问题是指:如果T已经对a,b有序,现在我们要将T按b排序。这其实是很常见的情况。多维分析的数据集一般总会按某套(比如按日期、帐户)维度已经排好序,但我们可能希望按第二维度(帐户)再排序或分组,是否可以利用这个特点提高性能呢?我们用a(i),b(i)表示表T中第i条记录的字段a,b取值。T对a,b有序,意味着如果a(i)=a(i+1)则必然有b(i)
2018年11月20日
其他

前半有序的大数据排序

最近碰到这么一个案例,情况可以简化总结成这样:数据库中有表T,其中有两个重要的字段a和b,a是一个时间戳,精确到秒;b是用户号;其它字段用来表示用户b在时刻a发生的事件属性。现在任务是:把数据按a,b排序导出。简单来讲,就是把SELECT
2018年11月13日
其他

如何将数据热导出到文件

随着时间推移,数据库中数据量会越来越大,如果把查询分析都挂到数据库上,有可能会影响到生产系统的正常运行。所以,一般都会将生产数据库中不再变动的数据定期移出到另一个分析数据库中,由分析数据库来承担查询分析的压力。不过,我们知道,文件系统比数据库有更好的IO性能,对于不再变动的历史数据,使用文件还可以采用更灵活的压缩技术。这样,如果我们把移出的数据存储到文件中,只要有好的计算引擎(比如集算器),那么基于文件计算将获得比分析数据库更好的性能,而历史数据常常巨大,性能提升很有意义。要实现这种结构,需要定期把历史数据从生产数据库中导出到文件,这看起来也没什么难的,导出是很常规的数据库操作。如果是冷导出,那确实没什么。所谓冷导出,是指在数据导出过程中,基于文件的查询分析系统会暂停使用,等导出完毕后再继续使用。比如在每天夜间没有查询工作的时候进行,把导出的新历史数据追加到原来的文件之后就可以了,有需要建索引的情况也可以同时维护好。但是如果是热导出,情况就不一样了。所谓热导出,是指查询分析系统永不停机,随时需要能响应请求。而数据导出本身也需要时间,在导出的过程之中仍然可能有查询请求进来。但是,这种有特殊格式的文件在追加和维护(索引)过程中,经常是不可用的,这时候就不能在导出数据的同时还响应查询请求了。采用数据库却没有这个问题。原因是数据库拥有事务一致性的能力,在数据写入(导出对于目标数据库来讲是写入)过程中,数据库仍然可以应对查询请求,并且不会使尚未完全写入的数据参与查询。不过,如果每批数据量写入太多时,也会给目标数据库造成较大的负担,数据库回滚机制的成本并不低。那么,我们怎么能够即享受到文件的高性能,又支持不停机的热导出呢?一个简单的办法是把数据文件拆细。比如,假如数据是每天导出,那么就可以每天保存一个文件,每次导出时形成新文件,在导出过程中原有的文件不变,可以继续使用。新的一天的文件导出维护完成后,在某个时刻才开始启用。比如每天0点开始导出前一天数据,假定一小时内能全部完成,则可以约定凌晨1点起启用新文件数据(即1点以后的查询将开始使用这个新文件)。这样的坏处是文件系统中积累过多碎文件,对管理造成麻烦,而且每次查询时都可能要涉及多个文件,运算代码不好写而且性能也会受到影响。在数据库一致性能力的支持下,再配合备份文件,我们还是可以实现将数据热导出成单一文件。准备工作:将数据文件复制成相同的两份:A份和B份,平时查询使用A份;在(生产)数据库中建立表X,用于记录当前查询正在使用的数据文件是A份还是B份,以及当前正在执行的查询。查询响应过程:从X中读出当前使用哪个数据文件,并在X中写入一条记录表示当前查询开始,需要生成一个唯一码,同时记录该查询基于哪个数据文件;使用相应的数据文件进行查询计算并获得返回数据后;将步骤1中写入的记录删除(用生成的唯一码),表示查询已经结束。导出过程:开始导出数据时,此时X中记录的当前使用文件为A,将这个值改为B,后续出现的查询将基于B进行;等待X中基于A的查询全部结束,即X中不再有关于A的查询记录,此时A已不再被任何查询使用了;现在可以导出数据追加到文件A,完成A的维护工作;将X中记录的当前使用文件改为A,再有的查询将转回基于A进行;等待X中基于B的查询全部结束;将A追加的数据也同时追加给B(这时只要读A,不会影响A上的运算),完成B的维护工作,B进入可用状态,导出结束。基本原理是在导出数据过程中使用另一个文件,完成导出后再换回来去维护备份文件。期间要考虑到查询的并发性,借助数据库的一致性确保不会发生写入和查询在同一个时刻针对同一文件进行。并发读写导致的错误,不是刻意或大规模使用时很难测试出来,在设计时要特别小心。许多机构期望数据库系统能支持T+0全量实时查询,在数据量很大时一般只能进行数据库扩容了(包括上述分库手段也需要扩容数据仓库),成本高昂。如果采用文件系统和生产数据库混合运算,就可以实现低成本高性能的T+0查询了,而热导出机制则是这个方案的基础(需要进行简单改造,在X表中记录文件中数据的截止时刻,超过此时刻的查询请求将转给生产数据库去执行)。不过,这个过程确实有些复杂,实现起来还是很麻烦,我们在乾学院上放一个以T+0查询为目标而实现的热导出例程(http://c.raqsoft.com.cn/article/1541494770016)另外,在新的集算器仓库版也将支持这一机制,直接向组表追加数据就可以了,集算器会自动处理热导出中的问题。当然,集算器不能依赖有数据库,它会自己实现一致性效果。数据蒋堂
2018年11月6日
其他

时序数据从分表到分库

这里的时序数据泛指一切随时间推移而不断增长的数据,比如通话记录、银行交易记录等。对于数据库来讲,时序数据并没有什么特殊性,可以和普通数据一样放在数据表中。不过,因为不断增长,积累时间较长后,这种数据的量常常都会很大。一个物理表的数据量太大时,就会影响查询和计算的性能。现代数据库一般都提供有表分区(PARTITION)的机制,就是把一个大表纵向(按行)分成若干区段,分区规则由数据库管理员来设置,对应用程序员来讲是透明的,可以和不分区的表一样访问,数据库会自动根据查询条件决定读取哪些分区的数据,这样的接口体验非常好。不过,在实战中,分区表的效果在某些场景下并不好,而且使用时也有些约束条件,并不总好用且能用的。结果,在实际业务中,我们常常会看到对于这种大数据采用手工物理分表的方案。所谓物理分表,就是人为将一个大表分成若干较小的物理数据表。因为时序数据的结构中一定会有一个字段来表示事件发生的时刻,而事件发生的数量一般来讲也会按时间段相对平均分布(大多数情况会缓慢增长,但讨论时可以忽略),所以最常用的方案就是按时间段来做分表,比如一个月数据对应一个分表,这种方式在金融、电信行业比较普遍。物理分表并不是数据库自动支持的方案,不能对应用程序做到透明,需要应用程序自己处理。在查询数据时一般都会有时间段参数,应用程序可以根据这个参数计算出该查询涉及哪些分表,然后将这些分表UNION起来拼到SQL语句的FROM后面。查询不涉及的时间段对应的分表不会被拼进来,这样就可以有效减少数据遍历的范围,从而提高性能。这个方案在单个数据库时没啥毛病,但是不是能推广到多个数据库的情况呢?数据量再大下去,一个数据库也无法承受了,而某些场景下又不允许我们上一套分布式数据库系统,毕竟分布式数据库是个沉重的工程,不仅造价高,而且维护管理都要复杂不少。这时候,我们可以摆多个数据库分别存储数据,类似物理分表的方案,也按时间段把数据分拆到各个数据库中,比如一年数据放入一个数据库中(一般来讲多个库会部署到多台机器上),这样就能分摊查询压力了。这首先会有一个查询范围的问题,如果查询的时间跨度超过了一个物理分库时,这时候就不能象分表时那样用UNION拼起来了,数据库无法执行跨库的SQL语句。不过,这个问题还不算严重,只是查询明细数据时,要把各个分库的返回数据拼接起来,这并不算困难。甚至,要求前端查询范围必须落在一个分库内也不为过(比如必须先选择查询年份),因为一个分库的数据量并不算少,这样用户体验略有损失,但也可以容忍。这种方案还会有压力不平衡的问题。对于时序数据,近期数据的查询频繁度远远高于远期数据,大多数查询都集中在最近一段时间中,存放近期数据的分库上任务就很重,并发较多时仍然会有性能瓶颈,而存放远期数据的分库却几乎没事干,并不能有效分摊查询压力。还有别的办法吗?可以采用蛇形分布。比如将多年数据分拆到10个分库中,可以按日期拆分,所有年份中1月1日的数据放到1号分库中,1月2日的放到2号分库,…,1月10号的放到10号分库,1月11号的再从1号分库轮回,…;其它情况的具体分法也可以根据时序数据的时刻字段的分布情况来决定。这样分下来,每个分库存储的数据量差不多也就是1/n,相对比较平均,还可以规避前面说的数据缓慢增长导致的不平衡;而且,无论近期数据还是远期数据的查询都会被分摊到各个分库中,看起来能够充分利用硬件资源了。还有点注意事项!蛇形分布时,每个分库中都有所有年份的数据,几乎每个查询都会涉及到所有分库的数据,不能只挑出某些分库来执行运算,这和前面说的分表方案的优化原理并不一样了。我们需要在分库中继续做分表,查询确实会涉及所有分库,但只涉及分库中的某些分表,这样仍然可以有效的减少查询范围,同时利用分库并行的优势。第二个问题:每个分库都可能返回数据,应用程序需要把这些数据再做一次汇总,而不能象单库分表那样用UNION推给数据库去完成。对于常见的明细查询,那只要简单拼接再排序就可以了,开发起来并不难;但如果涉及到分组汇总就会麻烦很多,应用程序员并不擅长编写这种运算,这时候最好借助集算器这类外部计算引擎来协助实现跨库汇总运算。当然,成本和条件允许时直接上分布式数据库就更简单,分布式数据库采用HASH方案基本上可以被理解成是蛇形分布的。数据蒋堂
2018年10月30日
其他

BI系统的前置计算

某机构上了一套分布式数据仓库,历史数据逐步装进了仓库,然后,基于数据仓库构建了BI系统(主要是多维分析)。刚开始,一切都顺利,但随着时间推移,基于中央数据仓库的应用越来越多,几年下来积累了数十个应用。这些应用都需要依赖数据仓库计算,导致中央数据仓库的负担越来越重,BI系统的响应开始变得迟钝起来。对于交互性很强的多维分析业务来讲,这是很难容忍的。咋办呢?扩容?这已经是个分布式系统了,节点数也差不多到了MPP型数据仓库的极限,再增加节点并不会有明显的性能提升了。更换数据仓库?就算有测试出性能更好的产品,敢换吗?几十个应用起码要全部重新测试一轮,否则谁能保证换了数据仓库后这些应用还能正常工作?这要协调多少部门才能动起来?对多维分析测试表现好的产品,对其它应用也会更好吗?如果导致其它应用的响应速度变得更恶劣又怎么办?中央数据仓库的选择,对于很多机构而言是个重大的政治任务,不大可能仅为某一个应用的问题而轻易更换。中央数据仓库暂不能动,就只能从应用端想办法。一个常见方案是采用前端计算,即把需要的数据放到应用端,由应用程序直接计算,不再请求中央数据仓库。技术上经常采用的手段是在应用端放一个前置数据库用来提供存储和计算能力。但是,简单放一个普通数据库却解决不了这里的问题:1.
2018年10月23日
其他

性能优化是个手艺活

大数据的技术本质就是高性能,性能优化也是程序员们的永恒话题。这里说的性能优化,主要是指在程序员的努力下能达到某种性能提升效果的过程。只要简单换台机器就能加速的事情,业主方要么早就做过了,要么就是条件不允许这么做。这时候,优化方案的关键在于算法,具体来讲,就是要设计出低复杂度的计算方案。我们说过多次,软件不可能提高硬件的性能,只有采用了低复杂度的算法,也就是计算规模有了实质性的下降时,才可能在相同硬件环境下获得更优的性能。不幸的是,这类方案通常都是定制化的,换一个场景可能就没有效果了。换句话说,这些方案是专门为某个计算任务设计的。以分组运算举例:如果我们事先知道GROUP
2018年10月16日
其他

数据分布背后的逻辑

在分布式数据库及大数据平台中,数据如何分布到多台机器中是个很关键的问题。因为很多运算是数据密集型的,如果数据分布做得不好,就会导致网络传输量变大,从而影响性能。一般来讲,分布式数据库会提供两种分布策略:对于大表按某个字段(的HASH值)去分布,大多数情况会使用主键,这样可以把数据分拆到多台机器上;对于小表则采用复制性分布,也就是每个机器上都会复制一份。但是,表的大小并没有绝对的判定标准,很大很小的表都容易识别并采取相应的策略,而那些数据不多不少的中型数据表又该采取哪种策略呢?要搞清这个问题,我们就要知道数据分布背后的逻辑,什么样的数据分布才算是好的?合理的数据分布能够有效地减少JOIN运算过程中的网络传输量!这也是数据分布的关键目标。大部分常规运算都容易分拆到多个机器上分别执行后再汇总,这样,原则上数据只要尽量平均分布就可以由各节点来分摊计算负担。但是JOIN不一样,它涉及关联计算,如果JOIN的两条记录不在同一个节点上,那就需要把它们先传输到一起才能进行运算,这种事当然越少越好了。那么怎样才能尽量避免JOIN过程中的数据传输呢?这又要回到我们已经讨论过多次的JOIN类型。回顾一下去年的文章《JOIN运算剖析》,我们把JOIN分成三类:外键、同维、主子。同维表和主子表的JOIN是在主键(或部分)之间进行的,主键不同的两条记录是不可能发生JOIN的,这样,如果数据已经按主键分布的,就不会发生跨节点JOIN的现象了。而外键表的JOIN,维表记录可能被事实表随意引用,无论怎样将维表分布,都有可能发生跨节点JOIN的现象,只有将维表复制到每个节点上去,才能避免JOIN过程中的网络传输。这样,我们就知道了:同维表和主子表要按主键字段去分布,而维表则要采用复制性策略,每节点都放一份,这样能有效减少跨节点JOIN运算。但这和大表小表有什么关系?一般来讲,记录事件的事实表会随着时间推移而不断增大,常常是大表,而这种表之间的JOIN大多数是同维表或主子表(比如订单及明细)关系。而用于外键指向的维表主要是用于存储一些不常变化的属性信息,相对要小一点。于是,本来是事实表要分拆分布、维表要复制分布的策略,就会表现成“大表”分拆、“小表”复制的特征了。明白了这一点,我们就不会再纠结大表小表的界限在哪里了,其实没有大小之分,而是在数据结构中的地位决定的。不过,关系数据库中并没有明确的事实表和维表概念,需要我们主动地去识别,有意识地设置分布方案。而且,一定要用主键去分布,随便找一个无关字段去分布,就起不到减少跨节点JOIN的作用了。有些大数据平台只提供自动(按大小)分布的方案,不能强制复制维表,也不能让同维表和主子表按主键同步分布,这时候分布式计算的效果就不会好了,在选择这些计算体系时需要特别注意。数据蒋堂
2018年10月9日
其他

从一道招聘考题谈起

润乾研发部在招聘时有一个笔试题:1/2,
2018年8月28日
其他

为什么我们需要C程序员

再说一个招聘的话题。大家可能知道,润乾的软件产品主体都是Java写的,几乎没有别的语言。但是,我们在招聘算法程序员时,从来都要求C语言背景,会不会Java反而无所谓,而如果没有C语言功底则免谈。事实上,现在润乾研发部几个做算法的程序员,都是来了公司之后才学习使用Java的。为什么我们会这么关注C/C++?润乾是做基础软件的,而编写底层代码的技术逻辑和界面有很大不同。底层代码会被千百次的调用,一个函数哪怕只慢了1个微秒,被重复调用100万次时也会导致秒级的延迟。相对来讲,界面程序就不在意这些,代码再慢也不可能慢过人的操作,这时候的重点就变成用户体验而不是性能了。想写出高效的代码,就必须深入理解计算机的运行原理,知道CPU、内存是如何工作的。应用程序员一般只关注业务功能的正确性,而一个好的系统级程序则不仅要保证正确性,还会习惯性地脑补出每一句代码被编译器翻译成什么样子了,最后会导致CPU和内存的哪些动作,从而判断出代码的效率。举个例子,new是Java代码中很常见的动作,但系统程序员却会很慎重地使用它,因为它涉及动态内存分配,是个非常复杂的任务,效率很低;但应用程序员则很少关注或了解这一点。这种能力,常常是被C语言编程训练出来的。至少,容易通过考察C语言经验知道程序员是否具有这种能力。而其它程序设计语言则难有这种效用。C语言的与众不同,关键在于其指针能力,包括函数指针。理解指针,本质上是理解CPU的工作原理,了解数据和代码在内存是如何存放的,CPU又是如何访问数据和执行代码的。说到底,其实是对汇编语言的熟悉。但汇编语言过于繁琐,C语言则是一个很好的抽象,即保留了大部分汇编语言的能力,又提供了更为宏观易读的描述方式。有了清晰的指针概念之后,也很容易理解C++(以及Java)中继承重载的具体实现方法,对于多继承(Java中取消了)也不会感觉到糊涂,也知道如何用非面向对象的语言(比如就是C语言)实现面向对象的机制(不仅能实现,反而会更灵活)。不过,并不是所有程序员都能体会到这一点,有些程序员仅仅是使用C语言的语法,而避开指针的运用。这样,C语言成为众多程序设计语言“之一”了。还有一个问题,我们为什么不直接用C语言写软件呢?这个主要是兼容性的问题。C语言发明得太早,早于许多操作系统,每个操作系统下的C语言总有些不一样,这样想写一个兼容性很好的程序几乎是不可能的事情。不过现在这个问题开始弱化了,服务器端的操作系统快被linux垄断了,所以迟早有一天,我们也会把程序用C语言重写一遍。这些本来就有C功底的程序员就能进一步发挥到作用。数据蒋堂
2018年8月28日
自由知乎 自由微博
其他

报表工具的SQL植入风险

所有的报表工具都会提供参数功能,主要都是用于根据用户输入的查询条件来选取合适的数据。比如希望查询指定时间段的数据,就可以把时间段作为参数传递给报表,报表在从数据库中取数时将这些参数应用到取数SQL的WHERE条件上,就可以根据不同参数取出不同数据来呈现了。不过,这样做要求事先把查询条件的规格做死,比如按时间段查询,那就要事先把WHERE写成
2018年8月14日
其他

内置的数据无法实现高性能

是指数据库之内。当数据量变大时,我们常常会感到数据库的性能下降明显,但是,无论怎样优化SQL(存储过程)都仍然与根据数据量和运算复杂度计算出来的理论性能相差甚远。这主要由如下几方面原因造成:1
2018年8月7日
其他

怎样生成有关联的测试数据

在向用户推荐新的数据处理技术,特别是涉及性能优化的场景时,经常会碰到生成测试数据的需求。毕竟,新方案要经过验证才能提交,而优化过程也不是一次就做完的,需要多次不断的迭代改进,这就需要有一套好的测试数据才能实施。用户常常也会提供一些例子数据,但一般不会很多。如果只是验证算法正确性,那用这些少量数据经常也可以了,但如果是验证性能,就还需要足够大的数据量才行。而用户的数据常常比较敏感,很多情况下不可能把全量数据提供出来,而且,数据量太大时也不合适搬来搬去。所以,最好还是能自己造出测试数据,特别地,还要根据用户提供的例子数据来造。如果只是单个表(比如多维分析的场景),那还相对简单。把例子数据复制n遍到期望的规模,或者干脆随机生成,过程中注意对主键进行一些处理保证不重复(比如不断地加1,具体手段视数据类型而定),大多数情况也够用。但如果涉及到多个关联表就麻烦了,因为运算中可能涉及JOIN,简单复制例子数据,可能导致JOIN结果集和例子数据的规模相近,而完全随机生成则很可能就关联不上使得JOIN结果集是个空集,下一步的运算就会建立在一个虚假的小结果集上,严重误导性能测试的结果。那么,该如何在多表情况下生成大规模测试数据时还能保证合理的关联性呢?1
2018年7月24日
其他

遍历复用

减少外存(硬盘)访问量一直是提高大数据计算性能的永恒话题,我们也讨论过列存、压缩等直接减少访问量甚至存储量的手段。除了这些存储层面的方法外,在算法和计算实现环节,也可以想办法减少外存的访问量。遍历是大数据计算中必不可少的环节。有时候,我们会发现在一个计算任务中,会有两次(或更多)涉及针对同一批数据的遍历动作。如果我们能有办法让两次遍历合并成一次,那么总的计算量(CPUT的动作)并没有差别,但硬盘的访问量会减少了一半,这样计算性能还是能得到提升,对于数据密集型计算的提升效果还相当明显。设有简化的帐目表T的数据结构中如下字段:账号A、日期D、发生地P,金额M现在我们想统计账号a1和a2的余额,用SQL写出来是这样:SELECT
2018年7月17日
其他

一些数据压缩手段

我们知道,外存(硬盘)的性能远远低于内存,即使是同样复杂度的运算(CPU计算量相同),如果能减少外存的访问量,也会大大提高整体性能。甚至有时我们需要用CPU换硬盘,即宁可多消耗些CPU时也要减少硬盘访问量,一方面CPU性能更好,另一方面是CPU比硬盘更容易并行,现代计算机的CPU核数常常远远超过硬盘的并发访问能力,数据密集型的任务应当更多地使用CPU的能力。如果能物理地减少数据存储量,也就自然而然地减少了外存访问量。列存是常见的减少外存访问量的手段,不过,仅仅是简单地采用列式存储,并不会真正地减少数据存储量。但是,使用列存之后,数据的可压缩性将大大提高。同一列的数据一般具体有相同的数据类型甚至近似的取值,大多数压缩算法在这种情况的工作效果要比针对杂乱类型数据时好很多,这样就能大幅度地减少数据存储量了。所以,列存不仅是在访问量上占便宜,即使访问表中所有列,列存的硬盘读取量要也比行存更少。在表的列数不多时,列存仍然有优势。通用的压缩算法不能假定数据有某种特征,只能是将数据当作随意的字节流去编码,有时并不能获得最好的压缩率。而且,高压缩率的算法常常会消耗过多的CPU,甚至于会到了拿CPU换硬盘都不划算的地步。所以,我们不能完全指望压缩算法,还要自己先对数据做一些手脚,人为地制造某些数据特征来利用,就可以采用较低压缩率同时低CPU消耗的压缩算法,也获得较好的压缩效果。一个常用的办法是排序。数据表的列中常常有许多是维度,比如地区、日期等。这些维度的取值基本都在一个小集合范围内,在大数据量时会有很多重复取值。如果数据是按这些列排序的,则相邻记录之间取值相同的情况就很常见,而这时使用很轻量级的压缩算法也能获得很好的压缩率,简单来讲,直接记录列值及其重复次数都能起到不错的压缩效果。排序时的次序也有讲究。要尽量把取值较长的列放在前面排序。比如有地区和性别两个列,地区的取值长度要大于性别,则先地区后性别排序的效果就要好于反过来的情况。先地区排序:北京男赵大北京男钱二北京女孙三上海男李四上海女周五先性别排序:北京男赵大北京男钱二上海男李四北京女孙三上海女周五前者存储:北京(3个),上海(2个);男(2个),女(1个),男(1个),女(1个);总字符数为8(只数字符个数,括号中的次数不记)。后者存储:北京(2个),上海(1个),北京(1个),上海(1个);男(3个),女(2个);总字符为10。地区的字符数比性别要长,把长的排到前面的存储量会更小。上面的例子中,我们还可以把”北京”、”上海”这些字符串事先转换成数字编码,而不要直接使用原始字符串,这样也能减少存储量。”北京”是个2个字符的串,如果用数字1代替就变成1个字符了。有些枚举形字符串列的取值很长,转换成数字编码会有很好的效果。做了编码转换后,在使用的时候会有些麻烦,需要再转换回来。不过,和获得的性能提升相比,这些麻烦还是值得的。整数(从字符串编码而来或本身就是整数)的存储也有些技巧。现代计算机的整数一般是32位的,要占4个字节。但很多整数很小,比如从省份转换过来的整数不会超过100,这4个字节的高3字节全是0,有些浪费;性别转换过来的只有1和2两种,而4个字节的整数甚至长于1或2个字节的“男”,”女“值本身了,这个转换反而不划算了。这时候就要设计合理的编码方式,不要让所有整数都占用同样长度的空间,让小正整数只用1-2个字节就能表示,大正整数以及负整数(负数很罕见)才要占满4个字节,甚至5个字节(否则信息空间是不够的),因为小正整数更常见,整体存储空间还是会变少。类似的技巧还可以用于日期存储上,一般来讲与某个确定日期距离较近的且过去的日期会更多一些,这时可采用某种编码方式让这些值变短,而距离远的以及将来的日期可以使用长编码。这些编码方案看起来很不起眼,一次只能减少一两个字节,但当数据量很大时效果就相当可观。对于应用程序员来讲,一般不会直接控制到这种细节层面了。不过,了解所选用的数据库(或别的有数据存储功能的产品)采用的压缩手段还是有必要的,这样才能更准确地预估运算性能。《数据蒋堂》官方技术交流群欢迎各路技术大咖入群,与作者交流(该二维码七天后失效)数据蒋堂
2018年7月10日
其他

用HBase做高性能键值查询?

最近碰到几家用户在使用HBase或者试图使用HBase来做高性能查询,场景也比较类似,就是从几十亿甚至上百亿记录中按键值找出相关记录来。按说,这种key-value式的数据库很适合用键值查询,HBase看起来就是个不错的选择。然而,已经实施过的用户却反映:效果非常差!其实,这是预料之中的结果,因为HBase根本不适合做这件事!从实现原理上看,key-value式的数据库无非也就是按key建了索引来查找。而索引技术,无论是传统数据库用的B树还是NoSQL数据库常用的LSM树,其本质都是利用键值有序,把遍历查找变成二分(或n-分)查找,在查找性能上并没有根本差异。LSM树的优势在于一定程度克服了B树在更新时要面对的复杂的平衡调整,并利用了硬件的特点,对于并发高频写入的操作更为擅长,在读取方面却反而有所牺牲。而对于很少更新的历史数据,用NoSQL数据库在按键值查找时,和传统关系数据库相比,并不会有优势,大概率还会有劣势。不过,对于只要找出一条记录的情况,这个优势或劣势是察觉不到的,就算差了10倍,也不过是10毫秒和100毫秒的差别,对前端操作人员来讲都是立即响应。所以,人们一般也不容易有直观的体验。但是,如果要找出成千上万甚至几十万行记录时,那感觉就明显了,100毫秒执行1万次就要1000秒了。上面说的用户应用效果差也是这种情况。用键值取数时,可以通过索引直接跳到数据所在地,这样硬盘访问量非常小,所以能做到很快。而如果键值非常多时,涉及的数据到处都是,硬盘访问量就会加大很多。而且数据在外存中是按块存储的,你不可能只读取一条记录本身的数据,而要把这个记录周边的数据都读出来,多读出的内容常常比要读的数据量还大很多倍。在总共只取一条记录时,即使这样,用户体验也不会有多差(10毫秒和100毫秒的差异);而要取出很多记录时,这个多读的内容也就跟着翻倍了,用户体验也就很糟糕了。如果这些键值是连续的,那么适当设计存储,让数据的物理存储也按键值有序,这样就不会有浪费的读取内容,性能损失也就很少。商用关系数据库一般会按插入次序存储数据,基本可以保证这一点。在存储块中会留有一部分空间应付少量改写,这样有些数据改动了也能大体保证连续性,按键值区间查找的性能也还不错。但HDFS没有改写能力,HBase在有数据改写时只能先扔到后面(LSM树也是这么设计的),这样会导致数据存储的不连续性,增加多余的读取,降低性能。如果键值不连续(这是更常见的情况),那这种多余读就无论如何不能避免,这时候想再优化的办法就是压缩,直接减少物理存储量。但是在这方面,HBase这种key-value数据库的表现也不如人意。这些NoSQL允许同一表中不同记录有不同字段,它不象关系数据库那样对每个表有一个所有记录统一的数据结构定义,这样带来了写入的灵活性,但势必要将数据结构信息附在记录上,导致存储量加大很多,给读取造成巨大的负担。而且,这种key-value方式也没法采用列存(严格地说,就没有列的概念),而列存+排序后可以极大提升压缩率(这个问题以后可以再专门讲)。HBase有个列族的概念,可以充当列的作用,这方面问题一定程度会有所缓解,但用起来并不方便。总结下来,大多数key-value数据库是为了高频写入而设计的,而不是为了高速读取!用来做高性能查询完全是个方向性错误。用于键值查找都不合适,而其它非键值查询的效果就更为恶劣(以前文中也说过这个问题)。明明不合适,为什么还有这么多人用或想用HBase来解决这个问题呢?可能是Hadoop名声太大吧,只要有大数据就会想到用Hadoop。而且,很多传统关系数据库也确实搞不定太大量的数据,数据量大到一定程度,存储都是问题,查询就无从提起了。不过,有些新的数据技术方案已经能够解决这些问题,延续了传统数据仓库的某些技术手段,比如事先确定数据结构、为读而优化的索引、列存及压缩等,再有合理的存储机制以支撑巨大数据量,这样就能得到比HBase好得多的性能体验。《数据蒋堂》官方技术交流群欢迎各路技术大咖入群,与作者交流(该二维码七天后失效)数据蒋堂
2018年7月3日
其他

BI系统中容易被忽视的数据源功能

用户在选购BI解决方案的时候,常常会更关注界面环节的功能指标,比如美观性、操作的流畅性、移动端支持等等。毕竟,BI是要给业务人员使用的,这些看得见的内容一般不容易被遗漏。然而,有些与数据源有关的后台功能点就可能被忽略掉。如果在项目实施时才发现就会非常麻烦,可能造成上线延迟,或者有些功能只能绕路而行。在选购BI系统时反而要特别注意这些功能点。1
2018年6月19日
其他

这个产品能支持多大数据量?

经常有用户会问这个问题,你家的产品能处理多大数据量?似乎是这个值越大产品就越牛。这个问题,其实没多大意义。能处理多大的数据量,还有个很关键的因素是期望的响应时间,在脱离这个因素单纯谈大数据产品的数据处理量,就不知道怎么回答了。考虑只有单台机器的简单情况。如果是希望秒级响应的OLAP式汇总,那么GB级都是挺大的数据了,几乎不可能有什么产品能处理TB级数据(除非有巨大内存)。而如果是数小时内完成的ETL运算,那么单台机器处理TB级也不是多大的问题。于是就会发生这样的现象:同一个产品能够处理某些场合下的TB级数据,却处理不了另一些场合下的GB级数据。不过,讨论一个大数据技术能支持的集群规模是意义的。大集群和小集群的实现技术很不一样,大集群需要有强容错能力和统一的管理机制,而小集群则不需要;而把大集群技术用于小集群,又会造成很多资源的浪费。某种技术面向多大规模的集群,一般是在设计之初就确定了的,并不容易随意改变。确定了期望的响应时间,以及可能支持的集群规模,这时候再来问某项大数据技术能够处理的数据量,才是个有意义的问题。《数据蒋堂》官方技术交流群欢迎各路技术大咖入群,与作者交流(该二维码七天后失效)数据蒋堂
2018年6月5日
其他

最简单的大数据性能估算方法

大数据的性能是个永恒的话题。不过,在实际工作中我们发现,许多人都不知道如何进行最简单的性能估算,结果经常被大数据厂商忽悠。这个办法我在以往的文章中也提到过,不过没有以这个题目明确地点出来。其实很简单,就是算一下这些数据从硬盘上取出来用的时间。除了个别按索引取数的运算外,绝大多数运算都会涉及对数据的整体遍历,比如分组汇总统计、按条件查询(非索引字段);那么,这些运算耗用的时间,无论如何不可能小于硬盘访问的时间,我们就能算出一个理论上的极限值。比如,有人宣称实现10T数据的OLAP汇总只需要3秒。那么这意味着什么呢?常见的15000转硬盘,在操作系统下的访问速度也就不到200M/秒,SSD会快一些,但也没数量级的提升,大概3秒读1G的样子。这样,从单块硬盘中读出10T数据就需要30000秒以上,如果想在3秒内完成汇总,那就需要1万块硬盘!作为用户,你是否做了这个准备呢?当然,硬盘及硬盘在不同环境下的速度不尽相同,可能更快或更慢,但总之都可以用这个简单的办法去估算。不知道自家硬盘的速度?那弄个大文件读一下试试就知道了,拿到实验数据再去计算会更准确。要强调的是,不能简单地看硬盘厂商标称的性能指标,在文件系统下,那个理想值常常连一半都达不到,还是实测的最可靠。这样,我们就能知道某个大数据问题最理想的情况能够达到什么性能,比这个指标还好的期望,在用于估算指标的硬件条件下都是不可能实现的,没有必要再去琢磨软件产品和技术方案了。这种估算也指明了一个优化方向,就是减少存储量和访问量。减少存储量当然不能减少数据本身,用于计算的数据一条也不能少,否则就出现错误结果。减少存储量要靠数据压缩的手段。10T的原始数据,如果有好的压缩手段,实际在硬盘上存储下来可能只有1T甚至更少,这时候3秒汇总这些数据就不再需要1万块硬盘了。在存储量不能再减少的情况下,还有些软件手段来减少访问量,常用的方法就是列存。一个数据表有100列占了10T,如果只访问三列进行汇总,那大概只需要访问300G数据,这时候3秒完成汇总当然也不需要1万块硬盘了。不过,大数据厂商在宣称10T、3秒这种性能指标时,一般不会明确指出采用压缩或列存技术后存储量和访问量能降到多少。这就容易给用户造成错觉,以为这个技术能够通用地解决大数据问题,而经常,有些数据的压缩率无法做得很高,对于访问列较多的运算列存也没啥优势。要更准确地估算性能极限,也要考虑减少存储量和访问量的手段。尝试一下自己的数据能有多大的压缩率(用常规的zip软件就可以),并且检查运算是否是从很多列中取出很少列的情况。《数据蒋堂》官方技术交流群欢迎各路技术大咖入群,与作者交流(该二维码七天后失效)数据蒋堂
2018年6月5日
其他

大清单报表的打印?

本期第一篇文章《大清单报表应当怎么做?》中,我们谈了大清单报表的呈现方法,其实有时候这些报表还需要打印,比如银行打印流水对账单。那么,打印是不是也要像呈现那样做一个缓存机制呢?没有这个必要。打印和浏览不同,一般是从头到尾过一遍就行了,过程中没有翻页的需求。这样,只要流式读入数据逐步生成打印页就可以了,不会发生内存溢出的问题。但这个做法仍然比较麻烦,特别是现代浏览器加强了安全控制,applet等插件经常被禁用,打印功能常常不能直接由报表工具提供,而要采用flash或PDF方式来实现。用flash可以做到流式读取,但并不简单,还会导致插件与后台耦合性过高,影响安全性;而PDF方式就是一次性生成一个文档,没办法实现这种机制了。我们来算算打印100万行记录是什么情况。假设一页纸能打印50行记录(这已经算多了),100万行记录就意味着2万页纸。2万页的连续打印,有多少打印机能做到这个指标?你的用户真有这样的设备吗?2万页纸大概有2米厚,什么打印机能把这些纸放进去?商用快速打印机一分钟也就30几页,就按50页/分钟算,2万页也需要7个钟头!作为一个机械设备能连续工作这么久是不容易的。而100万行记录需要占多大内存呢?一条记录算1K已经很大(毕竟一页要打印50行的),100万行也就1G内存。这对于前端用于打印的普通PC来讲并不难满足。这还是只算了100万记录的情况,如果把100万增加到500万,内存仍然可以承受,而打印机是万万吃不消了。也就是说,在现代计算机的内存容量下,打印这个功能采用全内存方式是没有问题的,几乎找不到需要流式读取的情况。作为一个要重复销售的商业软件,报表工具没必要去支撑这种极为罕见甚至根本不存在的应用场景。这个计算结果,看起来有点荒唐,读者可能会觉得可笑。但这确实是和用户沟通需求时真实发生过的事情,实际上喊的记录行数比500万要大很多,而用户并没有认真计算过它意味着什么。经过一些常规计算我们就会发现,虽然有些用户在叫,大清单报表的打印其实是个伪需求。大数据领域还有些类似的事,比如说10T数据想要3秒返回结果,用户却不会想到这很可能意味着1万块硬盘。严谨认真一点,会推出许多想不到的有趣结论。《数据蒋堂》官方技术交流群欢迎各路技术大咖入群,与作者交流(该二维码七天后失效)本期共有两篇相关话题文章请关注公众号或【阅读原文】查看大清单报表应当怎么做?大清单报表的打印?(本文)
2018年5月29日
其他

大清单报表应当怎么做?

在数据查询时,有时会碰到数据量很大的清单报表。用户输入的查询条件很宽泛,可能会从数据库中查出几百上千万行甚至过亿的记录。如果等着把这些记录全部检索出来再生成报表呈现,那需要很长时间,用户体验恶劣;而且报表一般采用内存运算机制,大多数情况下也装不下这么多数据。所以,我们一般都是使用分页呈现的方式,尽量快速地呈现出第一页,然后可以随意翻页显示,每次只显示一页,也不会造成内存溢出。那么,一般的报表工具或BI系统都是怎么实现这一机制的呢?绝大多数产品都是使用数据库分页的方法来做的。具体来讲,就是利用数据库提供的返回指定行号范围内记录的语法。界面端根据当前页号计算出行号范围(每页显示固定行数)作为参数拼入SQL中,数据库就会只返回当前页的记录,从而实现分页呈现的效果。这样做,会有两个问题:1.
2018年5月29日
其他

大数据技术的4个E

大数据的4个V说法在业界已经尽人皆知,这是指的大数据本身的特征。现在我们来考察一下用于处理大数据的技术应该具有的特性。为方便记忆,类似4个V,我们把这些特性总结成4个E,用户在选择大数据技术解决方案时可作为参考。01
2018年5月15日
其他

做基础软件很悲壮?

这几天中国数据库界出了一件悲伤的事情,南大通用创始人崔维力先生突然因病去世。我和崔先生神交已久,但却未曾谋面,一直希望有机会当面沟通讨教,这一下就成永远的遗憾了。崔先生的英年早逝(60多岁的年纪而已)又引发一个话题:做基础软件,特别是做国产基础软件,是个苦行僧的活。相比于应用软件,基础软件的技术含量高得多,熬得年头也长,累得死去活来,实际收益却很低。敢于做基础软件的,那都是悲壮之士。虽然我自己也在做基础软件,但这个观点却不能苟同。如果说基础软件厂商很悲壮,那ORACLE、微软是不是也很悲壮呢?我说他们富得流油还差不多。看来还得加个“国产”的定语才够悲壮。那么,国产基础软件为什么就悲壮呢?因为国产基础软件在市场上做得还不行,又苦又累却收益低的现象是客观存在的,这样确实显得悲壮。那么,这么苦逼的事,为什么还要去做呢?热爱祖国的情怀么?明知不可为而为之,那是真悲壮。我不否认可能有个别人真是这样的。但是,绝大多数选择从事这个领域的企业,包括润乾在内,更重要的理由是:赚钱!特别地,像ORACLE、微软那样赚大钱!赚钱,这事说破了当然一点也不悲壮了,但事实就是这样。做基础软件,确实周期稍长见效略慢,特别是想构建一个生态,那难度非常大,风险也不小,但我们不能只看到这些缺点。基础软件才是真正能做到零成本复制而重复销售的,只要做到市场认可,那它是非常赚钱的业务,我估计全中国上市的软件公司利润加起来也未必赶得上一个ORACLE(没有认真调查过,只是感觉)。高风险高投入(包括时间成本)一定要对应高利润才合理的。而且,这事也不分国内国外,基础软件因为其通用性,只要能赚钱,就会是全世界都赚钱,盆满钵满。俗话说:理想很丰满,现实很骨感。虽然想赚钱,但事实上国内的基础软件厂商,包括润乾在内,到目前为止都还没怎么发大财(也可能有个别发达的我不知道罢),这是因为做基础软件的原因吗?我不知道每家企业的具体情况,反正我们不是这个原因。现在做得还不够好,主要是因为自己的经营管理能力还有问题。做一个企业,并不是产品战略方向对路就一定能成功,还有太多执行层面的因素,各方面都要做得足够好才可能把一个企业带向成功。我们还要继续锤炼自己,练好内功,而不是去抱怨选了一个看起来很悲壮的方向,事实上我们选择的是金矿!各个企业还没做好都会有各自不同的原因,但我想,赖到基础软件头上都是没有道理的。一个常常被问起的问题:既然想赚钱,为什么要做基础软件而不去做看起来更容易赚钱的应用软件?我的回答一向是:我们只会做这个。这是真的。对润乾来讲,其实并不存在做别的就能迅速发达的可能性。每个领域都有相应的特点和难度,不擅长就是不擅长,轮不到我去赚的钱不琢磨。简单说,我们只是在做自己擅长且喜欢的事,只是朴素地想通过这种事来赚钱,基础软件有更大的重复销售量来获得超额利润,基础软件难度大更适合我们这种以技术为本的公司,仅此而已。我们不选择悲壮,悲壮也没什么用。说到情怀,当然还是有的。这主要体现于坚持忍耐以及传说中的工匠精神,这能够树起更高的技术门槛,结果还是可以转化成利润。至于“国产化”,因为我们是个中国公司,在客观上也一定程度地能起到这个作用,但这并不是目的,而是副产品。在主观上我们没打算背、也背不起这个责任。这些观点,并没有对崔先生不敬的意思。对于创立了两家知名企业的崔先生,我是很敬佩的。事实上,只要是在市场上靠实力打拼出来的企业家,我都很敬佩,而南大通用也是几家国产数据库厂商市场化程度最好的。我想,中国基础软件厂商真正在市场上打出一片天地,赚到大钱,才算是告慰崔先生最好的行动吧。数据蒋堂
2018年5月8日
其他

国产操作系统还能怎么做?

一家之言,开个脑洞。操作系统在市场上的关键点,并不在于进程管理、文件系统这些看起来很核心的东西,这些东西真地可以抄(借鉴一下没关系的)。操作系统要普及成功,关键在于上面开发技术的方便性,也就是开发工具的易用性以及API的丰富性。开发工具就是操作系统的用户界面,决定了用户体验;下层核心是为上层API服务的,也可以说是被API决定的,而不是倒过来。从这个意义上讲,Windows的成功,是因为Visual
2018年4月24日
其他

做基础软件要投入很多钱?

现在有个说法,国家对基础软硬件的投入太少,经常会说微软、Oracle、Intel这些巨头每年的研发费有多少多少,我们的投入连个零头都不到,当然做不出什么象样的东西了。看起来还真是,似乎还要再加大投入才行?我不懂芯片的事,不知道是不是需要花很多钱才能建出基本的实验生产环境,但软件的研发成本还是比较熟悉的。在我的意识中,国家在这方面投入的钱并不是太少了,已经足够多了。和国外巨头比研发费,你不能拿微软现在花了多少钱来算,而要拿当年它做DOS时花掉的钱来比。基础软件要做到全面普及,确实需要持续的投入完善,长时间来看,这个成本也确实很高。但是,把产品做到能用、做到用户愿意来买单、做到可以养活自己,可能也需要较长的时间,但并不需要太多的钱,后期完善的成本可以也必须用利润来支付。我没统计过Linux做到用户愿意用投入了多少人月成本,MySQL又用了多少?但无论如何,我想这个成本都会远远小于国家对基础软件的投资额度。那么,为什么国家支持的基础软件都做不成,花了这么多钱也还是做不好?这个原因已说过多次了,因为做这些事情的基本战略是抄,而从来没敢想过超。抄,你当然要花很多钱才能做出个类似的,因为人家已经花了很多钱,你又没有三头六臂,凭啥比人花的钱能少很多?抄,只能抄出表面的东西,抄不到产品背后的商业逻辑,不知道为什么要做这个产品,只是为了做这个产品而做。这样做出来的东西在市场上毫无竞争力,于是还得持续地花钱,结果当然你会觉得钱总是不够,而这种情况下,投入再多也是无济于事的。但是,我为什么要做得和人家一样呢?有人说,国外产品的用户体验已经非常好了,你做得不如人家怎么竞争呢?其实,在创新技术面前,用户体验根本就不是个事。刚做出来的汽车跑得没有马车快、坐着也没马车舒服,用户体验在很多方面都明显要更恶劣。但是,它不用吃草喝水、不会生病受惊,就会有那么一些用户愿意为这些特性忍受其它恶劣,然后,逐渐地,速度也提上去了,舒适度也好起来了,….。类似地,经常被拿来说的生态问题也不是个事。只要你有过人之处,解决了用户的痛点,自然有用户会接受你。生态不是一天两天建成的,但也不是没希望的。去抄才没什么希望,只是人家的生态下混混日子。当然,你要能抄到前几名(象AMD之于Intel)那也行,市场总容得下几个竞争者,但我们这些一向处于十名开外的选手,你抄什么抄啊,你只能去超!创新不容易,因为过程中试错的反复很多,所以周期会很长,风险也会比较大,但是真不需要花很多钱。十几个人能做的软件已经相当复杂了,在迭代试错的阶段,人再多也没什么意义。润乾做报表工具,耗了近5年时间才做到赢利,时间是不算短,但投入了多少呢?研发队伍不过10人,一年不到100万(15年前)。现在我们做数据计算和数据库,这个难度更大,已经耗了10年了,但研发队伍也不过25人(前几年更少),就算再扩一倍,成本顶天也就是每年千万级别,肯定没有人家的零头多,但你看我能不能做出一个敲打Oracle的东西出来!本期共有三篇相关话题文章请关注公众号或【阅读原文】查看国产数据库通通都没戏!国产操作系统还能怎么做?做基础软件要投入很多钱?(本文)
2018年4月24日
其他

国产数据库通通都没戏!

这标题摆明了就是招人骂,一下子把国内做数据库的同行们都得罪了,甚至连自己都没落下(我也算做数据库的,而且当然也是国产的)。这观点已经有N年了,而且也多次讲过。这次正好有个热点来蹭,就把它写出来。既然蹭热点嘛,那就不怕标题党了。不过,还是要先澄清一下,这里说的“没戏”,并不是说国内厂商做不出一个可用的数据库来(事实上早已做到了),而是指做不到在市场上普及,击败国外产品,获得足够的市场占有率(至少在国内市场上)。这样也就没太多机会发展完善,最后很可能不了了之。还有,那些互联网巨头们做给自己用的情况也不在讨论范围之列。这个逻辑其实很简单:作为追赶者,采用技术跟随战略是没希望的。目前做国产数据库的,绝大多数仍然采用四十年前的关系代数作为理论基础,有些甚至是直接拿一些开源产品改出来的,基本上就是技术跟随战略。而国外巨头们做这些事已经好几十年,人强钱多积累厚,那么我们凭什么赶得上人家呢?这无关乎人员素质,我见过不少国家扶持的数据库厂商中的技术人员,能力相当强,其中也不乏能耐得住寂寞的有情怀者。但是,人家的人才也不差啊,我有很多大学同学都在美国数据库公司任职,你又不比别人多长两个脑袋?你会的别人都会,甚至还比你会得更早,你凭什么赶呢?这时候,仅剩的指望就是对手犯错误。确实,大公司也会犯错误,但是这个机会对于我们这些排在十名开外的追赶者来讲也是没有意义的。第一名犯了错会被第二名补上(历史上就曾发生过),还有第三第四名在盯着看,无论如何也轮不到我们,你总不能指望前N名一起犯错误吧。这个道理不仅适用于中国,也适用于全世界。所以,不够发达的中国没有,发达的欧洲日本也没有(SAP收购了Sybase有可能冒出来,它的HANA一定程度符合后面说的道理,但概率也很低),数据库巨头只存在于美国。而且,对于复制成本为0的通用软件,只是做得便宜些也不行(这个法子对冰箱彩电这种生产成本不低的业务有效)。国内份额大概占不到全球的5%,国际巨头现在还不关注这块市场,随便做做就行了。如果真要占到30%了,那人家就会认真研究对策了,随便降个价咱都受不了。指望政府的大棒把人家打出去?这个,一方面没啥出息,另一方面在这对外开放的年代,咱也不能说这话啊,至少不能明目张胆地说啊。那,还能怎么办?创新!超越!我们必须比对手做得更好,还要好很多,这样才有机会,才能弥补生态不完善的问题。而要做得更好,就需要有颠覆性的技术,在新技术面前我们和对手是站在同一起跑线上的。对于巨头来讲,要向股东交代,就要保持稳定的收益,它还不能随便革掉自己的命,
2018年4月24日
其他

人工智能中的“人工”

自从AlphaGo赢了之后,人工智能就变得非常热门了。不过,大家在关注“智能”时,却很少把注意力放在“人工”上,似乎感觉上了人工智能之后,一切都能自动化了。其实,这份智能的背后有着大量的“人工”,还有相当多不能自动化的事情。这里的人工主要体现在两个方面:
2018年4月17日
其他

存储和计算技术的选择

前一阵子公司有个售前来沟通某个用户的情况:数据量比较大,又涉及很多复杂的关联计算,在数据库中用SQL计算性能很差。本来这种场景是比较适合集算器的集文件(集算器特有的压缩二进制格式)存储并计算,但据说这个用户的历史数据还会经常变动,而集文件目前没有提供改写能力(为了保证压缩率和性能),也就不容易直接用。于是想推荐用户采用nosql产品做存储,集算器在上面做计算。赶快打住!如果用户真的听了,那会恨死我们。这个场景中有三个要素:数据量大、复杂计算、频繁改动。为了解释这三者的大致关系,我画了一个不太严谨的图:NoSQL数据库在存储时不考虑事务一致性,而且许多NoSQL产品对key-value结构(要改的数据肯定要有个key)的数据都会采用LSM树等优化手段,一般情况比RDB常用的B树性能要好,所以对于频繁改的应用,NoSQL的效率会比较高。相反,RDB虽然也能频繁改,但为了事务一致性等因素,效率就会低于NoSQL。但key-value结构的NoSQL却不擅长大数据计算,除了按key找value比较快以外,涉及到遍历(这是家常便饭)的运算都不灵光,主要是因为value是无确定结构的,每次取出数据要现解析,而且数据结构也会多存很多空间,所以大数据计算效率就会远远低于RDB(所以上述场景一定要打住,绝不可以推荐NoSQL)。RDB频繁修改后会导致数据在硬盘上的连续性很差,也不容易做好压缩,这样大数据量遍历的性能也不会太好。而RDW在RDB基础上做了运算优化,可以事先整理数据,放弃了复杂的写一致性能力,这样对于大数据计算就会有更好的性能。但反过来,频繁改就不适合了。RDB和RDW都采用SQL体系运算,对于简单查询计算没太大问题,但过于复杂的关联和过程性运算,由于关系代数的局限性,很多优化算法无法实施(我们已经多次说过这个问题),所以在复杂运算场景下性能不佳(也就会发生上述场景的现象)。集算器是为了复杂计算而设计,可以实现更优的算法获得更好的性能。但如开始所述,目前的集文件又不支持改写,所以它只适合解决复杂运算,而难以面对频繁改的场景。集算器其实比RDW在大数据计算性能方面更好,不过作为计算引擎并不太关注存储,而大数据需求中还是会比较在意的可维护管理能力就要弱了。集算器进一步发展出来的仓库版将支持少量修改的存储方案,这样可以在保证复杂运算能力的基础上再提供数据维护能力,可以逐步替代数据仓库,不过也不合适频繁修改。而另一个方向的云库版则更注重结构多样性,同时也支持事务一致性,能适应频繁改,而且有集算器提供复杂计算能力,但同前面分析NoSQL的理由,这时候它又不适合大数据遍历了。那么这三样都想要怎么办呢?难道就只能见鬼去?其实也有办法,只要肯多花钱买大内存(还可能要集群)把数据全装进去,这三样就能并存了。毕竟,有钱能使鬼推磨嘛,呵呵!数据蒋堂
2018年4月10日
其他

数据蒋堂新一年

时光匆匆,《数据蒋堂》已经走过一年。在这里,也庸俗地感谢一下读者们的一路相伴!老实说,这一年写这玩意儿有点难度的,主要原因是时间周期卡得有点死,每周一篇执行起来是不太容易,一开始小看了这个频度;另外是篇幅问题,一周一篇讲一个问题,也不希望太短。结果有时工作忙了来不及搞,就会感觉是个负担了,而且偶而还会发生凑数现象。接下来,我想还会继续写下去,不过,打算调整一下风格:
2018年4月3日
其他

区块链技术的一些疑问

暂时没有文章存货,按新定的风格可以等着有货再发,不过新一年开篇还是不要空着,就拿寒假期间的学习笔记来充个数,也作为一个不限于数据库技术话题的例子。文章在刚写出来的基础上做微量修改下面是我在学习了解区块链技术过程中产生的疑问,思考问题的过程中也会让自己对这项技术理解得更深刻。我不算初学者(知道区块链已有五年之久了),但一直也没有深入学习,不能算链圈的专业人士,所以可能孤陋寡闻,不能确认这些问题是不是已经被解决了,或者根本就是问得毫无意义,权当学习笔记。1.
2018年4月3日
其他

【数据蒋堂】第48期:Hadoop中理论与工程的错位

Hadoop是当前重要的大数据计算平台,它试图摒弃传统数据库的理念,重新构建一套新的大数据体系。但是,这并不是件很容易的事,在Hadoop的设计和实现中能看到一些先天不足的地方,其中一点就是把理论问题和工程问题给搞拧了。所谓理论方法,是指试图解决问题的一般情况,设计通用的算法能适应尽量多的情况,并努力使算法的复杂度降低。在研究问题时不会考虑具体环境下某个具体动作是否可以执行以及该动作消耗的资源,而会假想一个理想的环境;工程方法则相反,不需要考虑普遍的一般情况,而是针对某个具体问题,充分利用当前环境提供的便利,并充分考虑每个具体动作消耗的资源(包括时间),尽量高效率低成本地实现目标。原则上,在设计体系模型时要理论化,而在编码实现时则要工程化,这样才能做出一个即能解决足够多问题且效率也可接受的产品。但是,Hadoop在不少地方把这个事情搞反了。本该由理论解决的一般性问题被用工程方法简化成特定问题,而具体实现时又把本该在工程层面优化的问题想得过于理论化。导致的结果就是能方便解决的问题太少,而解决问题时效率又太低。一句话说就是理论问题工程化,工程问题理论化。MapReduce是Hadoop中关键的并行机制,经过多轮封装改进,这个模型现在仍然是Hadoop的算法核心。这个方法认为可以将一个大任务拆成一些无关的小任务,分别处理(Map)后再按某个键值归拢到一起再做处理(Reduce)。Hadoop实现好这个框架后,程序员就只要写Map和Reduce动作即可了,这样就编写并行程序就会简单很多。MapReduce用来处理求和、计数等简单问题也确实有效,但世界可没有这么简单!琢磨一下用MapReduce去实现JOIN运算的麻烦度就知道了(具体做法可以从网上找到,这里不细说了),而这种有关联的运算在现实需求中相当常见,其它一些次序有关的运算用MapReduce实现也很困难。也就是说,MapReduce算法能够方便描述的运算太少了,这个模型的适应面太窄。基于这个理论实现的产品,面对复杂运算时基本上起不到减少工作量的目标,甚至根本无法应用。本该在理论上研究出更通用的算法,却被工程化成简单情况。然而,Hadoop在实现MapReduce框架时,却又缺乏对具体情况的考虑,而是假想了一个理想环境。Hadoop认为集群节点机可以无穷多,任何性能问题都只要增加节点就可以解决,这样就没兴趣去关注单机性能了,肆意地跑出多个进程而很少采用经常效率更高(但不总是)的多线程手段;Hadoop不考虑外存读写的巨大延迟,Map过程
2018年3月27日
其他

【数据蒋堂】第47期:Hadoop - 一把杀鸡用的牛刀

自动化管理管任务分配机制:这样规模的集群,显然不大可能针对每个节点提供个性化的管理控制,否则工作量会大到累死人,必须采用自动化的管理和任务分配手段,而这并不是件简单的事情。2.
2018年3月20日
其他

【数据蒋堂】第46期:大数据集群该不该透明化?

这好像是个多余的问题,大部分大数据平台都把集群透明化作为一个基本目标在努力实现。所谓集群透明化,是指把一个多台机器的集群模拟得像一个巨大的单机,只是系统管理层面知道体系是由很多单机集群而成,应用程序则应当尽量少地感受到集群的存在,在概念上可以把整个集群理解成一台机器,甚至在代码级都可能和单机运算兼容。透明化主要有两个方面。一方面是数据存储,提供统一的集群文件系统或者数据库系统,应用程序不需要关心数据具体存放在哪里了,系统将自动寻找合适的节点,并提供一定的冗余容错机制;内存的透明化相对要困难一些,有时需要应用程序知道集群的存在。另一方面是任务分配,系统负责将大任务拆分成小任务并分配给各个节点机去执行,在有节点故障时能再将任务分配给其它节点;有时任务拆分比较困难,也需要程序员事先设计好拆分方案。透明化显然有好处,可以降低理解难度,开发程序时和单机情况差不多,也能提高代码的兼容性。从这个意义上讲,只要能透明化就都应当去做,除非是实现难度太大(比如上面提到内存和任务拆分)的情况。那么,为什么还要提出该不该透明化的问题呢?因为,透明化难以获得最优的性能,而高性能对于大数据计算又是一个关键的目标。高性能计算方案因运算目标和数据特征而异,并没有普适的优化方法。好算法需要特定的数据分布及任务分配方案,而使用系统自动的机制就很可能无法实现了。有些优化手段还是互相矛盾的,如果不做透明化则可以根据场景选用哪种。而实现透明化时,为了保证在任何情况都能正常工作,经常只能选择较保险的方案,常常这并不是性能最好的方案。比如在做JOIN运算时,我们可以从业务上区分维表和事实表,也事先知道维表的容量,如果维表数据量较小,则可以将维表主动存储到所有节点中甚至读入内存,而只把事实表分段存储到节点中,并按此分布设计更优的算法能。而透明化方案不能做这些假定,要处理一般情况,就不能区分维表和事实表,也不能假定维表足够小。有些计算平台能够临时测定数据特征以采用更优的计算
2018年3月13日
其他

【数据蒋堂】第45期:大数据计算语法的SQL化

SQL,而Scala反而少很多。其它一些新的大数据计算体系一般也将SQL作为首选的计算语法,经过几年时间的混战之后,现在SQL又逐步拿回了主动权。
2018年3月6日
其他

【数据蒋堂】第44期:谈谈临时性计算

其实也就是编程序了,常用来对付临时性计算的编程方案有三种:以Java为代表的高级语言、以SQL为代表的数据库语言、以Python为代表的脚本语言。
2018年2月27日
其他

【数据蒋堂】第43期:报表开发的现状

2008年开始研发不依赖关系型数据的计算引擎,历经多个版本后,于2014年集算器正式发布。有效地提高了复杂结构化大数据计算的开发速度和运算效率。
2018年2月22日
其他

【数据蒋堂】第42期:RDB与NoSQL的访问性能

关系数据库也是很常见的数据存储方式。本质上讲,数据库其实也是一种特殊的二进制文件,但它的性能会弱于直接写在操作系统下的文件,主要原因在于数据库通常都要提供数据更新的能力,这就会产生影响性能的因素:
2018年2月12日
其他

【数据蒋堂】第41期:文件的性能分析

二进制文件中,我们会将各种数据类型对应的内存字节直接写出到文件中,再读取时也只要直接取出重新装载成内存数据,没有复杂的解析过程,也不需要判断和识别非法情况,这时性能就会好很多。
2018年2月6日
其他

【数据蒋堂】第40期:倍增分段技术

索引区的i号位可以看成是一个区块,对应由i号位内容指向的那条记录起到第i+1号位内容指向的记录之间的所有记录(含头不含尾)。在这一轮追加叶,相当于每个分段中只有一条记录。
2018年1月23日
其他

【数据蒋堂】第39期:数据分段讨论

因为硬盘不适合频繁随机访问(即使固态硬盘也不适合频繁小量的随机访问),为了保证遍历性能,我们希望每个线程要处理的数据在硬盘上要尽量连续存储,而不是频繁跳跃。
2018年1月16日
其他

【数据蒋堂】第38期:JOIN延伸 - 维度其它应用

不过,需要指出的是。无论是E-R图还是总线图,只要画正确时,其中的关联线数量是差不多的,这是数据本身的关系决定的。总线图并不会比E-R中的关联线更少,但改变了看待方法后会更清晰。
2018年1月9日
其他

【数据蒋堂】第37期:JOIN延伸 - 维度查询语法

当我们从数据库结构中已经抽取出维度之后,就可以较方便地解决这个问题了。显然,这几个date都是有维度的字段,我们把这个维度命名为DATE,那么上面语句可以写成这样:
2018年1月2日
其他

【数据蒋堂】第36期:JOIN延伸:维度概念

对于地区、产品这些常规维度,数据库中都会有对应的地区表、产品表,那么这些维度就对应了这些表的主键字段,符合我们定义。而销售额、产量等属性则不可能对应到某个表的主键,所以确实也不是维度。
2017年12月26日
其他

【数据蒋堂】第35期:JOIN提速 - 有序归并

使用有序归并实现并行计算时需要把数据分成多段,单个表分段比较简单,但两个关联表分段时必须同步对齐,否则归并时两个表数据错位了,就无法得出正确的计算结果,而数据有序就可以保证高性能的同步对齐分段。
2017年12月19日
其他

【数据蒋堂】第34期:JOIN提速 - 外键指针的衍生

一台机器的内存装不下,可以多搞几台机器来装下,把维表分段放在多台机器上形成集群维表,然后就可以继续使用上面的算法并获得一次解析多个外键和易于并行的好处。同样地,集群维表h
2017年12月12日
其他

【数据蒋堂】第33期:JOIN提速 - 外键指针化

将事实表sales中的外键字段productid,转换成指向维表products记录的指针,即productid的取值就已经是某个products表中的记录,那么就可以直接引用记录的字段进行计算了。
2017年12月5日
其他

【数据蒋堂】第32期:JOIN简化 - 意义总结

采用简化后的JOIN语法,就不可能发生漏写JOIN条件的情况了。因为对JOIN的理解不再是以笛卡尔积为基础,而且设计这些语法时已经假定了多对多关联没有业务意义,这个规则下写不出完全叉乘的运算。
2017年11月28日