Antutu是用户常用的一款智能设备跑分软件。如下图所示,它从四个大类来评估一台移动设备的性能,分别是CPU、GPU、UX和MEM。Antutu最终给出总分、一级汇总得分和二级得分,人们一般习惯使用总分来量化设备间的性能。

Antutu在手机上的跑分结果截图

但近期我用Antutu的Android版本做性能测试时,发现UX大类中的UX图形处理-鱼眼、Blur和JPG解码一项分数明显比竞品低,便想查清楚原因。但此项中又包含三个子项,究竟每个子项的分数是多少呢?每个子项究竟是怎样进行评测的呢?一番网上搜寻后,我并没有找到Antutu官方出的分数计算报告白皮书,也没有在设备Log中或是其他地方找到详细分数的输出。那么似乎只能进入Antutu评测软件内部窥探一番了。

注意:破解Antutu并篡改分数等行为是被官方禁止的,本文只做Antutu分数的获取过程分享,测试用Antutu版本为V7.1.0。

0x1 梳理Antutu跑分逻辑

首先解压Aututu主apk包,并同时使用apktool再将主apk解压反编译备用。

1
> apktool.bat d "antutuv7.apk"

Antutu Apk

接下来使用dex2jar工具将Aututu主apk包中的两个dex文件转换为jar包,并使用JD-GUI打开分析。

搜寻后发现非常显眼的是jni这个类。从中可以看到定义了Antutu每一个子测试的编号,能查询到我们想看到详细分数的三个子项分别是20、21和22号。并且还能看到jni类中关联着的Native函数,其实现都位于lib\x86|armeabiv7\libabenchmark.so中。

接下来不难发现,Antutu的跑分主流程在com.antutu.benchmark.service.BenchmarkService的f函数中,因为其中有大量的Native函数调用。

BenchmarkService

Antutu 3D跑分为第一项进行,逻辑复杂,暂时跳过分析。后面的每一项测试的大体流程为,如果该跑分项目由Native层进行测试,比如多线程测试,则先由a(int)函数通知UI线程某项跑分开始了,然后通过dc.a(int)判断该跑分是否可以在Native层执行,并等待2秒后才开始真正测试。由于此处的Java类和方法有部分做了混淆,所以需要根据每个函数的具体实现猜测其功能。

Java invoke Native

通过IDA打开libabenchmark.so后,我们发现Native层并没有做更加完备的防护,搜索benchmarkV6函数,便可以找到更多测试函数的入口了。

benchmarkV6

如果该跑分项目在Java层进行,则先跑分,再通过jni.benchmarkProcessUX接口将分数导入Native层。比如测试XML(14)。

xml

接下来我们继续研究UX图片处理的相应逻辑,我们寻找20~22编号的测试并详细查看其逻辑。

ux

其中,JPG decode比较简单,使用Java的BitmapFactory.decodeByteArray测试。分数为5秒内decode的次数。由于是纯Java实现,我们可以将相应的代码自己实现后测试,但结果显示JPG decode并不是导致UX图像处理跑分低的根源。

而FishEye和Blur都使用了Native实现。搜索fisheye关键字,我们很快能看到其Native测试实现。

fisheye

0x2 获取Antutu 主应用的实际跑分值

虽然我们已经看到了Antutu测试的部分实现的反编译结果,但除了直接分析,还有什么样的方法能更快地获取到Antutu的详细分数呢?

一种可能的办法是自己写一个Android App,并参照Antutu的JNI接口定义来定义类,比如说定义一个com.antutu.aaa.bbb.jni的类,并将libabenchmark.so去出打包到我们自己的App的Apk中并申明加载。加载后既可直接调用Native方法进行测试,或者是通过恢复Antutu存放分数的文件来直接读取已经存储的分数。这种方法应该是可行的,但比较麻烦。

经过不断的搜索,我们发现Antutu的详细跑分在一个内部flag开启的时候,会自动写到/sdcard/.antutu/last_result.json中。在跑分流程的末尾,可以发现这样一个dc.a(context)这样一个函数,它在dc.b()返回true时被触发,而dc.b()只是单纯地返回了dc.f这样一个静态变量,并且并没有找到在其他地方有被修改。

dc static

dc a

此时,一个简单的想法便是如果能将dc.f的默认值改为true,则可以获得这个分数了。

modify smali

重新使用apktool b指令重建Antutu的主Apk,并使用jarsign重新签名。但安装后发现Antutu卡死。

这是为何呢?寻找原因后发现Antutu在Native层做了自身的签名验证,验证不通过的话会不断sleep卡死App。

test sign

详细观察代码后发现,result需要返回0才能通过判断,而绕过验证签名的方法为将if(v21)判断绕过即可。一个简单的办法就是将这里对应汇编的cmp操作全填nop即可。
最终可以获取到Antutu自动打印的详细分数了。

0x3 获取Antutu 3D应用的实际跑分值

然而分析发现,主要是Fisheye得分较低。但分析Native代码无果,没有发现明显的优化点。将3D App屏蔽后,发现三者在Fisheye上分数都低了很多,并且十分接近,因此判断Fisheye分数是3D App中GPU加速的Fisheye测试与CPU Fisheye测试结合在一起得出的,而在GPU FishEye上得分低拖累了我们的分数。因此接下来我们需要继续探究Antutu 3D App。

Antutu 3D是使用Unity开发的,使用dnSpy看到可以看到其内部逻辑。
在OnTestPhysX找到了测试主逻辑。

测试方式为3秒中统计图像处理次数。

onTestPhysX

检查逻辑后还发现,Antutu对一些特性不支持时,暴力地降低分数,比如不支持computeShaders时,分数只有1/3,不支持ARGBFloat时,分数再减半。

为了获取到真实的分数,将debug的开关翻转,重新打包Antutu 3D APK,运行后可以在Logcat中看到分数的输出了。

3D

课程作业要求

  • 《数据仓库与数据挖掘》机器学习分类方面的课程作业
  • 本题目为针对时间序列数据进行活动分类
  • 题目的数据集是通过在胸部的穿戴设备采集而来的三维时序数据
    • 1.csv ~ 15.csv 分别表示从 15 位接受数据采集的参与者身上采集而来的三维数据
    • desc.txt数据集格式说明文件
    • 数据特点:活动之间的连续性
  • 具体的任务
    • 单一活动类识别
    • 活动转换点检测
    • 多活动类别识别

报告

报告最初是使用Google Docs写的,为了方便排版,就直接使用hexo-pdf这个插件嵌入PDF了

项目代码

Github Repo,细节详见Readme.md。

简介

问题

题目:输出斐波拉契数列的图灵机。

要求:设计图灵机,输入n,然后输出斐波拉契数列的第n项。
(需要有图形界面和测试例子)

功能

  • 图形化的通用图灵机编辑器。
  • 半无限带图灵机模拟器,以及可视化调试环境。
  • 使用上述环境实现题目要求的图灵机,并进行了局部性能优化。

开发说明

本次作业使用Web技术开发,其中vis图形库用于图灵机的设计与调试可视化,npm包管理,grunt用于工作流控制。
项目目录如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ tree . -L 1
.
├── build // Javascript文件中间结果存放
│   └── bundle.js
├── Gruntfile.js // 定义Grunt自动化任务,如Browserify,Uglyfy
├── node_modules // 使用npm install安装得到的依赖包
├── package.json // 描述项目依赖等信息
├── public // Web根目录
│   ├── bundle.min.js // 打包、代码混淆后的源文件
│   ├── bundle.min.js.map // 调试信息
│   ├── img
│   ├── index.html // Html布局文件
│   └── vis.min.css // vis图形库所需的层叠式样式表文件
├── readme.md
├── src // 程序逻辑源文件夹
│   ├── app.js // 主程序
│   ├── turing.js // 图灵机编译与模拟器
│   └── util.js // 工具函数
└── tmws // 序列化的图灵机文件

  • 依赖包安装:npm install
  • 编译、打包源文件:grunt
  • 启动服务器:cd public && python3 -m http.server

使用说明

  • 最简单的图灵机(读0写1,读1个1便接受)的设计、运行与调试,见视频Demo-1。
  • 斐波拉契数列图灵机的读取、运行,见视频Demo-2,输入输出格式见图灵机设计描述。
  • 在线Demo,地址
  • 代码,Github Repo

Demo1

Demo1

Demo2

Demo2

斐波拉契数列图灵机的文件见twms文件夹。

从视频Demo中可以轻松地看出图灵机的图形化设计、保存装载、编译重置、运行调试过程,
如下两张图展示了图灵机编译与运行过程中出现的错误提示。
运行时错误提示
编译时错误提示

图灵机设计

输入输出格式

工作区示意:<迭代次数计数器 C >1<当前计算的Fib数 M >1<上一次迭代计算的Fib数 N >

输入格式: 0{n}101

输入样例:

  • n=1: 0101
  • n=3: 000101
  • n=5: 00000101

在上述样例中,从首位开始的连续的0的个数描述了n,后面紧跟的1是分割符号,
再后面一个0表示1,这是由于斐波那契数列的第一位数为1,再后面跟着一个1作为分割符。

输出格式: 读头指向连续0的个数为所求的第n位斐波那契数列的值,0{fib(n)}10{fib(n-1)}

输出样例:

  • n=1: $1[读头>]01
  • n=3: $$$1[读头>]0010
  • n=5: $$$$$1[读头>]000001000

计算思路

  • 单次迭代过程:将M复制一份到N后的空白区域,然后将M和N的分隔符移动到新复制的M的前一格。目的是计算将M+N赋予M,M赋予N。
  • 迭代控制:若C不为0,则将C的计数器减1,然后执行上述迭代操作,并回到起始位置;否则移动读头到M的位置。
  • 复制控制:逐个Bit将M复制到N后的空白区域。

转换图表示

第一个图灵机示意图

局部优化与效果

观察上述图灵机,一个性能优化点在于在复制M的时候,新复制的M可以不全部写为$,再后期写为0,而可以改为将第一位标记为$,而后面的位都直接复制为0。这样后期就可以省去再将新N全部改写为0的操作了,而第一位标记为$是为了方便在新M和N之间放置分界符1。改动如下图所示:

第二个图灵机示意图

针对如上的性能优化点,收集两个图灵机的步数随N的变化数据,结果如下:
优化效果

可以看出,虽然第二个图灵机总是比第一个图灵机步数少,但性能的提升占总步数的比例却非常低,步数随着N呈指数级别上升,而优化的步数只呈现线性增长。

工程实现

使用Vis实现图绘制与操作

Vis.js是一个基于浏览器的动态Javascript可视化库,其中封装好了高度可定制化、可视化的网络模块。为了实现图灵机的动态编辑,我基于Visjs开源的示例程序,加入了图灵机设计中需要的元素,以方便用户通过可视化的界面创建图灵机。

图灵机的绘制与操作逻辑主要位于src/app.js中,主要描述以下功能:

创建图灵机设计绘图区

程序界面由index.html描述,主要分为两部分。网络编辑与可视化区域由id为mynetwork的网络绘图区,和id为network-popUp的网络信息编辑窗口构成。

控制面板由编译与调试信息,网络保存与载入控件,条带编辑区域和图灵机运行控制控件组成。在document.body.onload方法中可以看到对应控件的事件回调函数。

定义图中点和边的对应操作

createNetwork函数生成网络中初始的两个实例节点,并在mynetwork创建网络实例。其中的options参数描述了适用于图灵机的网络配置信息。
options.layout定义了网络的点和边的布局,物理效果(点排斥,边吸引)可以更好地设计图灵机中的状态和转换。
options.manipulation定义了网络中的六个基本事件的响应,点、边的增删改。对于点和边的增改,我们都给用户弹出信息编辑界面,并将数据保存在响应的点或是边中。对于新创建的点和边,赋予初始值。对于特殊的点和边,比如开始状态和结束状态,相应地修改点的特性以方便用户查看。

保存与载入

使用saveWorkspace函数将网络信息以JSON格式保存在文件中。
使用restoreWorkspace函数将用户选择的文件中的JSON信息重新解析为网络信息,并使用该网络信息创建网络,刷新界面。

图灵机的编译

图灵机的相关逻辑编写在src/turing.js模块中,对外暴露图灵机的主要数据结构以及图灵机的控制函数,同时需要提供信息输出接口,对网络中元素的高亮操作接口以及网络绘制回调。

图灵机数据结构中保存有如下信息:图灵机转换表,起始状态,读头位置,当前步数,当前状态,输入条带以及其他控制信息。

图灵机的编译函数为turing.makeTable。通过图的遍历,将图形化的图灵机翻译为图灵机状态转换表。状态转换表是一个二维映射表。第一层映射为状态到该状态的所有转换的映射;第二层映射为输入字符到某状态的其中一个转换的映射。

通过reset,完成图灵机运行前信息的初始化。

图灵机的运行与调试

图灵机的运行函数为start,单步调试函数为step,其中运行函数不断调用单步函数,每一步的时间间隔可调。

单步函数每次以当前状态,当前读头下的字符作为输入,在图灵机转换边中,通过两层映射找到对应的转换,并按照转换中的下一个状态、下一个字符和读头移动方向更新图灵机状态信息,在信息更新后,调用高亮函数在图灵机的可视化界面上提示当前图灵机的运行状态,并调用绘图回调刷新用户界面;如果未找到,则停机并输出调试信息;如果图灵机下一步没有转换并且当前状态可以接受,那么图灵机成功停机并输出信息。

数据库研究者将大数据描绘为一个决定性的挑战。我们需要集中精力在五个研究热点上才能最大程度地利用现在众多的机会。

数据库的一小队核心研究人员通过周期性的例会,交流探讨领域内的发展状态,并指出未来的核心发展方向。例会已经成功举办了多届,比如1989,1990,1995,1996,1998,2003,2008。28名数据库研究员和2位受邀的嘉宾于2013年10月在加州大小Irvine分校的Beckman中心举行了为期两天的讨论,延续了这一传统。
虽然参会人员被限定在了30人,这是为了最大程度地保证参会人员相互之间进行良好的互动,但他们分别代表了来自不同方向、资历和地区的研究兴趣。本文总结了本次会议的一些结论,更加详细的报告和与会人员的展示可以在这里找到。

本文关键点

  • 在2013年十月,来自数据库研究领域的三十位代表讨论了领域内的研究状态,并展望了未来的研究方向。
  • 大数据被认为是领域内的一个决定性挑战。他们提出了五个相关的挑战:开发可伸缩的数据基础建构;应对在数据和数据管理中日益增加的多样性;提出端到端、数据到知识的处理管线;拥抱云计算的广泛普及和协调众多不断变化的人的角色。

与会人员很快就大数据带来的决定性的挑战达成了一致。大数据问题的崛起是由于以下三个主要趋势。

  1. 廉价的存储、传感器、智能设备、社交软件、多玩家游戏和让家、汽车、电器和其他设备互联的物联网让数据的产生的渠道越来越广;
  2. 多核处理器、固态硬盘、廉价的云计算资源和开源软件都让产生巨量的数据越来越容易;
  3. 数据管理正变得自治化。数据的产生、处理和消耗并不仅仅是数据库专家的专利了,数据管理已经成为了决策者、领域专家、用户、记者和工人的日常。

随着这些数据浪潮的到来,从未出现过的巨大容量的数据需要被捕捉、存储、查询、处理并转变为知识。这些目标同十几年来被数据驱动的研究团体的目标非常吻合。很多早期的大数据系统抛弃了数据库管理系统的一些核心思想,例如声明式编程和事务数据一致性,从而换取伸缩性和在商用硬件上实现容错性。不过,在最新的大数据系统中,人们重新发现了这些核心的约束思想,并接受了一些在数据库领域长久以来的思想精髓。在这些核心约束和精髓上构建起来的数据库社区,有能力为大数据技术带来改革性质的改善。

不过大数据也带来了极大的挑战,提出的解决方案需要对数据管理解决方案的设计、实现和部署进行破坏性的革新。大数据的主要特点是容量、速度和多样性。数据库研究团体致力于推动容量和速度的研究多年,设计出的研究方案基础触及到所有的企业。而大数据浪潮带来的海量数据,让研究人员需要对已有的解决方案进行更加深入的探讨。

多样性来源于不同的数据源。

  • 首先,不同格式和质量的数据集成和分析成为了一个难题。这是数据库领域内一个长久存在的话题,不过从原始数据到可以使用的知识从目前来说还是需要耗费大量的人力。大数据加重了这个问题,这导致了数据处理管线中出现了一个主要的瓶颈;
  • 第二,需要处理大数据的平台也有很多的变数:硬件基础设施、处理软件框架、编程语言、系统和编程抽象;
  • 最后,用户也带来了复杂的需求和不同的偏好。想设计一个数据管理解决方案应对这么多的多样性是一个极大的挑战。

除了三个V(容量、速度和多样性),众多的大数据应用选择在云计算平台上部署,这不论是公有还是私有云。这需要提供性能可预测、互操作灵活的新技术。很多的应用需要人来解决很多难以自动解决的语义理解问题。这包含了某个领域的专家或是很多工人,或是整个互联网(比如维基百科)。这就需要帮助人们便得更加高效的新技术,与此同时尽量降低解决这些问题需要的人力能力等级。

总而言之,大数据为研究人员带来了极大的挑战。我们必须重新思考教授数据管理的方法,重新审视我们的研究历程,适应这数据科学这个新研究分支的出现。

研究的挑战

本次会议指出了五个大数据带来的挑战:

  • 可伸缩的数据基础设施,提供大容量高速的服务
  • 应对大数据管理中的多样性
  • 端到端数据处理
  • 云服务
  • 在数据生命周期中人的职责

其中前三个挑战分别对应着大数据的容量、速度和多样性。后两个对应着云计算环境下大数据应用的部署和管理人在其中职责的变更。

在已有工作下,这些挑战并不是额外孤立的方向。近年来,数据库研究团体已经加强了关系数据管理系统的核心功能,并衍生出很多新的方向。会议中,诸多问题被提出:安全、隐私、数据属性、社交、移动、时空变化、私人、带有情景的、能耗敏感和科学数据管理的问题,其中很多与现有的大数据挑战有交叉,可以在相关领域深入讨论。

很多工作是与其他计算机科学领域合作完成的,比如分布式系统、人工智能、知识发现、数据挖掘、人机互动和电子科研。在许多案例中,这些专有的领域带来了新技术的灵感,并结合数据库研究人员的专业知识一起提出健壮的解决方案。这些高效地跨方向合作应该被大力提倡。

可伸缩的大规模/快速数据基础设施

并行和分布式数据处理

在数据库领域,大规模结构化数据的并行处理已经成功实现,这让众多基于SQL的产品在企业中大规模使用成为了可能。另一个成功应用在于数据仓库,数据库研究人员定义了数据立方(为了联机分析处理,OLAP)的关键概念和并行查询的策略,也更好地支持了实物化视图和数据复制。在大规模普通商用机器上,分布式领域已经用一些编程模型,例如MapReduce,在处理更大的非结构化数据方面取得了成功。在此基础上,更加高层的语言让更广阔的开发者群体可以使用大数据平台的扩展性。如今,像是Hadoop之类的开源平台已经在处理非结构化数据方向上获得了广泛的采纳,原因在于它MapReduce的编程模型、大规模的分布式存储系统和更高层的应用语言(Pig和Hive),这让传统的公司也开始使用这一技术。

查询处理和优化

声明式语言在大数据处理方向上广泛的普及,越来越多的人关注到代价敏感的查询优化器和面向集合的查询引擎的重要性。这将充分利用大规模多核机器集群的潜能,做到“纵向”与“横向”扩展。这就为处理过程监控带来了挑战,比如一个用户可以分析管理哪一个查询耗时过长或是占用了太多的计算资源。为了适应未曾分析过的数据格式,并减少数据分析阶段数据传输的代价,查询处理器需要将数据样本抽取、数据挖掘和机器学习整合在处理流程中。

新兴的硬件

对于一个数据中心的规模,随着更快的网络、服务器间完全二等分带宽的网络和远程内存直接访问技术的发展,顺序处理和网路传输的速度比率不断变化。除了通用多核处理器组成的集群,更多专用处理器也可纳入考虑范围。成功的商用数据库机器已经展示了软硬件协同设计的数据库管理系统的潜能。研究人员得考虑利用专用处理器,比如GPU、FPGA和应用专用集成电路来处理超大规模的数据集合。这些通信和处理技术革新将带来并行和分布式查询处理算法的重新考量,因为之前的算法是基于相同的硬件环境设计的。

经济的存储

数据库研究团体必须学会怎样利用最新的内存和存储技术。和传统的磁盘相比,固态硬盘虽然每GB价格较贵,但I/O操作延时小。多种非易失随机访问内存技术正在实验阶段,它们拥有不同的速度、能耗和耐久特性。

要考虑服务器扩展存储和网络扩展存储。例如HDFS的分布式的文件系统,虽然是服务器存储但却是网络共享的,这是两种方式的结合。怎样最好地利用一系列的存储?这像是重新回到了以前的共享内存或是共享磁盘或是不共享的旧的争论中,之前已经画上句号的争论随着硬件的升级可能需要重新被提起。

高速数据流

对于高速生成的数据流,我们需要新的可伸缩技术来应对数据流的处理和消化。比如说,应对不统一的内存访问和多层内存层级下的访问速度限制,这些数据流的信息密度低,所以需要在线实时处理后就丢弃掉不用的数据。更进一步,这些数据的样本和聚合统计信息需要被挑选出,并存储下来以应对稍后的查询和分析。对于这样的数据,渐进的查询处理提供了增量和部分查询结果,而在数据不断涌动处理的同时,逐渐地精确度提高,这种渐进式的处理十分重要。

后绑定模式

对于被保持下来的数据,在其生命周期中可能只会发生一次被处理的机会(有可能从未被处理到),预先在数据库中对其进行处理和索引就非常不经济了。这样的数据应该被以二进制的方式保存下来,在被处理的时候再把它结构化解析。结果有可能是以自描述的方式存储的,键值对形式例如JSON,以预定义的模式进行解析或是使用数据挖掘进行演绎。为了提供在此情况下数据处理的最优方式,我们需要数据库可以以后绑定模式在原始文件上进行处理的查询引擎。

一致性

在今天,数据捕获、更新和简单快速地数据访问成为了新需求。对于非结构化数据来说,处理高速的数据捕获和更新需求导致了NoSQL系统的发展。目前有很多这类系统,提出了一系列的事务处理模型。大多是仅仅提供了基本的数据访问和弱原子操作保证。这让基于这些系统构建可信系统成为了难题。不过,大数据中一个新兴的团体通过键值存储提供了类数据库的成熟特性。对于一些用用来说,存储的数据对于一个公司来说就是“事实和真理”。对于其他应用来说,例如物联网,存储的数据反映着外界世界的情况,通过这些信息,应用可以做出相应的反映出。这就为重新考虑保证数据流通和一致性的编程模型和机制带来了机会,基于这些模型和技术,可以保证更加健壮的应用。

指标和基准

可扩展性不应该仅仅用数据的容量和每秒查询次数来度量。还应该以数据处理方的总体消耗(包括管理和能耗),端到端的处理速度(从原始数据获取到最终知识的输出),系统的稳定性(可以容忍部分数据的解析错误)和可用度(尤其对于入门用户来说)。为了度量这么多的指标,需要提出新的基准测试。

数据管理中的多样性

不存在通解

在今天,和传统的企业数据相比数据的种类、形式和规模都多种多样,形成了这个数据驱动的世界,传统的数据储存在为分析专门优化过的数据仓库中。现在数据通常以不同的表示形势,以不同的应用程序接口、查询工具提供出来。这样看来,不太可能一个大型的数据系统可以符合所有这些灵活性的要求。我们期望看到不同类别的系统涌现,每一个类别都解决一个专门的需求(比如数据去重、大型图数据分析、多种科学实验,实时流处理),或是发觉一个特定的硬件平台(比如廉价机器的集群或是超多核心的服务器)。为了解决这些问题,需要并行计算和高效地处理数据量大于内容容量数据集的专业知识。

跨平台集成

给定系统的多样性,平台需要被集成或是联合起来,为跨系统分析数据提供可能。这和让数据的格式透明化相关,更和跨数据系统间的数据访问和数据流动的性能优化相关。这也要求管理系统需要跨设备和数据中心运行。在网络连接不稳定的情况下,设备离线的情况逐渐地变得常见,这就带来了可信数据的输入,查询处理和数据不一致的挑战。

编程模型

一个多样、数据驱动的世界需要多样的编程抽象,方便开发者在大型数据集上进行操作。一个面向大数据的数据分析语言,比如一个SQL的超集并不能满足所有人的需求。更进一步,用户必须用他们最熟悉的语言来进行数据的分析:SQL,Pig,R,Python,领域特定的语言或是一个低级别的限制性编程模型,例如MapReduce,或是Valiant的批量同步处理模型。同样建议开发可重用的可以多种语言绑定的中间件,比如可伸缩的矩阵计算库、数组操作、程式化地迭代执行模型等。另一个可能成果丰硕的方向在于,为新领域的数据分析开发领域特定的分析语言,并直接将这种可扩展、并行处理的思想结合在其中。

数据处理流程

为了应对数据的多样性,我们需要平台可以处理“生”和“熟”的数据。被处理过的“熟”数据可以是很多种形态:表格、矩阵或是图。系统会运行端到端的工作流,其中多种类型的数据被混合处理,比如说,通过SQL查询出的数据接着使用R进行分析。为了统一不同的系统,懒计算有时有一定的优势————懒数据解析、懒转换、懒加载、懒索引和创建视图,及时(JIT)查询计划。大数据系统应该变得更加可互操作,就像是Lego积木一般。
集群资源管理器,比如Hadoop2.0的YARN,在系统层面提供了一些灵感,Hadoop生态圈的工作流系统和科学工作流的工具也给了我们一些启示。

端到端的数据处理

数据库研究团体需要给予端到端的数据处理更多的关注。在多年研究的成果中,我们很少看到能不在人进行关键性干涉的情况下,从原始数据逐步提取到知识的工具。对于大多数步骤来说,干涉的人需要对计算机有深入的了解。

数据到知识处理管线

原始数据到知识管线基本就是如下步骤:数据获取、选取、评估、清洗和变换(也被称为“数据扯皮”)、抽取和整合、挖掘、联机分析、结果总结、证明和解释。除了更大的规模外,其他显著变化的包括了数据和用户的多样性。现在,数据以各种形式出现,通常非结构化和结构化会以结构化的形式结合起来用。在分析管线的每一步中,数据工具必须利用人类的反馈,并且必须是相关领域的专家,而不是IT专业人员。例如,一个记者想要从一个记录有罪犯数据的表格中清晰、统计和发布数据。工具也必须为新出现的数据科学家团体量身定做。

工具的多样性

既然没有一个全能的工具可以应对所有的数据分析场景,我们需要多种工具,每个都需要一个原始数据到知识的处理管线。它们必须可以被无缝地衔接起来,可以被入门菜鸟和专家使用。每个工具提供最佳实践来给予使用者充分的指导。

工具的可定制性

工具必须可以利用相关的领域知识,比如字典、知识库和规则。它们应该可以很轻易地进行领域的定制,有可能通过机器学习来自动化这一定制化过程。人工编辑的规则的地位依然很高,但是由于很多分析应用需要极高的精确度,例如电子商务。对于这些应用,分析师经常要写规则来覆盖一些边缘个例,着对于学习和泛化就不可行。所以,工具必须为编辑、评估、应用和管理人工规则提供支持。

开源

在此领域内很少有工具是开源的。大多数都需要较高的授权费用,并只针对数据处理步骤中的特定步骤。这样造成的后果是,现有的工具不能直接从数据研究团体方面获得贡献。

理解数据

解释、证明、过滤、总结和可视化是让分析工具更好用的几个关键点。捕获并且管理恰当的元信息是让解释、出处、重用和可视化成为可能的一个关键点。可视化分析逐渐获得了数据库、可视化和人机交互领域研究人员的关注。在本领域持续的研究成果对于应对大容量数据的用户十分重要。

知识库

我们对于一个目标领域获知的知识越多,工具越能好地分析这个领域。结果是,为了获得更好的理解数据,创建、分享和使用领域知识蒸逐渐地流行起来。这样的知识通常被储存在知识库之中,其中描述了一个领域中非常多重要的概念和关系,比如一个知识库存储了数十万的生物学研究人员和他们发表的研究成果、隶属关系和专利。这样的知识库被用来提高数据到知识管线的准确性,回答领域内的一些问题,并找寻相关的领域专家。很多公司已经构建了这样的知识库来回答用户的查询、对文本进行标注和支持电子商务,分析社交网络数据。知识库是比较准确的,这导致了一些社区维护的“知识中心”的发展,它们提供了查询、分享的工具,并使用知识库进行数据分析。

在此话题已经不断有工作进展的基础上,我们需要更多的精力被投入一下工作上,提供工具帮助不同能力层次的用户协同地构建、维护、查询和分享领域内专业知识的知识库。

云服务

云计算目前大致可以分为三类:

  • IaaS,服务就是虚拟化后的硬件
  • PaaS,服务是虚拟化后的基础设施软件,例如DBMS
  • SaaS,服务就是一个应用软件服务,比如一个CRM解决方案

从一个数据平台的角度来看,PaaS是最理想的。用户可以上传数据到云上,和传统数据库一样通过SQL进行查询,并选择性地分享数据和查询结果。这一切都不需要考虑需要租多少个机器实例,使用什么操作系统,如何在多机器间分表和怎样进行数据库调优。虽然一些类似的服务已经出现了,比如Salesforce的Database.com,Google的Big Query,Amazon的Redshift和Microsoft的Azure SQL Database。我们还没有达到最理想的服务。如下,我们列出了一些关键的挑战来实现数据Paas的愿景。

可伸缩性

数据的迁移代价非常高。NAS让数据库引擎可以轻易地进行扩展,但是网络延时和带宽限制着数据库的性能。SAS降低了这些限制,但是服务器宕机将会造成服务可用性降级,最终影响SLAs。

一个公开的问题是是否云存储服务可以支持事务和分析,缓存怎样才能被最好地嵌入整个系统中还是不太明确。为了提供伸缩性,数据PaaS的数据库引擎和分析平台需要可以正常地运行,即使是在底层资源可能随时由于业务需要进行扩容的情况下。对于付费的优质用户,提供优先级更高的服务。

数据冗余复制

对于地理位置分散的数据中心,其相互之间的延时让数据的备份并保持一致性、高吞吐和低响应时间有了很大难度。多主数据备份是一个不错的选择,这是由于在不同复制副本上发生冲突的更新可以被自动同步。不过这个编程模型对于主流的编程人员来说不太直观。所以,主要挑战在于如何最优地权衡可用性、一致性、编程复杂度和代价。

系统管理和调优

对于Data PaaS来说,不存在数据库和系统管理员这两个角色。所以,管理工作必须被自动化,比如容量估计,资源供给和物理数据管理。资源管理参数也需要以极高的响应度被自动计算出,例如缓冲池大小和权限管理。

多“租户”

一个数据PaaS的竞争力来自其价格要比内部部署的解决方案低。这就需要提供商将多个用户的需求打包运行在相同的硬件资源上,通过分享来减少开销。首先,数据得在用户之间被隔离防止数据泄露。这可以通过将用户的数据库分散在不同的文件中,或是通过虚拟机进行隔离。不过,这对规模小的数据库非常不经济,并且想在多个VM之间均衡分配资源也是困难的。其他解决方案可以是用户分享一个数据库和数据库引擎,但需要特殊地身份限制保证安全。第二,用户想要定义了性能和可用性的SLA,提供商也希望SLA来提供分级分价格的服务,不过,怎样定义SLA让客户易于理解,让服务商易于实现是一个挑战。实现的困难在于保证客户之间的性能分离,即一个客户突发的高访问量不会导致另一个客户的服务被降级影响到。

数据分享

云计算让分享达到了从未有过的高度。一个问题是如何支持入数据管理等核心功能的云上合作。还有其他问题包括:怎样找到有用的公开数据,怎样将私有管理的数据和公开数据相关联,怎样在网上找到优质的数据,怎样以细粒度做数据分享,怎样在分享数据和计算的同时分担开支,怎样给数据定价。云计算页造成了新的数据什么周期问题,比如在云服务提供商发生故障的时候应该怎么做,怎样在使用者和提供者完全没有关联的情况下,持久保存数据。云计算也会驱动数据管理方面的工具创新,比如审计、法律条文的健全。

混合云

将在线数据服务、自部署的服务和移动设备结合的需求是存在的。其中的一个使用场景就是工作负载分流。比如在一般情况下,用户可能在他们的私有云中运行应用,不过可能在流量峰值到来的时候使用公有云进行负载分流。还有一个例子是物联网,例如车辆会将本地的传感器数据聚集后上传其中一些到云平台中,并且基于从多方聚集的数据获得控制信息。物联网系统与从多个传感器和移动设备获取的信息流有关,并且必须应对间断性的网路传输和有限的电池资源,这对于实时造成了挑战,并且页可能让云端的数据管理成为了一个关键任务。

人在数据生命周期中的职责

回到企业驱动的数据管理时代,人员的职责非常的明确:

  • 开发者开发数据库和以数据库为和谐的应用
  • 商业分析师使用(基于SQL的)报表工具,查询数据库
  • 终端用户产生数据,查询或是更新数据库
  • 数据库管理员对数据库和工作流进行监测与调优

现在,一个人可能将扮演数据生命周期中的多个角色,而有些角色可能需要众包来解决。所以,对于查询的理解和优化、判别相关和可信的数据源、定义和持续优化数据处理管线、可视化相关的特征模式、获得查询结果、将任务分解为大量小任务供专家或是用户来解决,人的因素需要被详细地考量。我们将人的角色分为四个大类:生产者、管理者、消费者和社区成员。

数据生产者

今天,基本上所有人都可以通过手机、社交平台、应用和可穿戴设备生成源源不断的信息流。对于数据库社区一个关键的挑战是设计算法和激励方式指导人们生产并分享最有用的数据,同时保证自己需要的隐私不泄露。当人们生产数据的时候,我们怎么帮助他们快而准确地添加元信息。比如说用户上传照片后,Facebook就会自动地将人脸区域都标注出来,这样用户就可以选择是否对人脸进行标注。另一个例子是一个自动帮推文加话题标签的工具。我们还能做什么类似的工作吗,或者我们还可以提供什么通用的原则和工具?

数据管理者

数据不再仅仅存在于数据库中,只被DBA或是被IT部门所掌控了。现在,很多人都有权利对数据进行管理。众包是其中的实现方法之一。这其中的一个关机挑战是基于一个不完美的人类数据管理者,获取到一个高质量的数据集合。我们需要构建允许用户轻松管理数据的平台,并扩展相关的应用来与管理者合作。对于这种以人为中心的挑战,数据源头和解释将成为一个重点,隐私与安全也同样重要。

数据消费者

人们总是提出诸多的数据使用方法和更加混乱的数据,这提出了很多挑战。在企业中,数据消费者通常了解如何针对一个结构化的表格写SQL查询。而现在数据消费者有可能不知道如果生成一个查询语句了,比如说一个希望在一个结构化数据集上找出“在佛罗里达有100,000人口以上所有城市的平均温度”的新闻工作者。如果想让人们自己找出这些问题的答案,就需要提供新的查询界面了,比如基于多点触摸的界面而不是传统的SQL。我们需要多种整合了可视化、查询和导航的界面。当用户的查询不明确的时候,需要提供给用户其他浏览、探索、可视化和挖掘数据的方法,让数据消费更加简单。

在线社区

人们想要创建、分享和管理其他社群的数据。他们想合作构建社群对应的知识库、Wiki和处理数据的工具。比如说,很多研究人员在Google Scholar上面创建了自己的主页。
对于我们来说,挑战就是帮助社群构建数据挖掘、分享和探索的工具。

社区带来的挑战

除了研究领域的挑战,数据库领域还面对着不少社区难题。这包含数据库教学、数据科学和研究文化。有一些是大数据带来的新难题,有一些则是被大数据加剧了的旧问题。

数据库教学

目前标准的数据库课程已经难以与现在的实际需要相衔接了。目前的教学内容集中植根在上世纪八十年代,那时内存相比于数据库的存储容量来说非常小,I/O就成了很多数据库操作的瓶颈,并且当时的服务器都配备相对较为昂贵的单核处理器。而现在,很多数据直接可以在内存中装下,多核处理器让并行和缓存行为成为了衡量数据库的一个标准。虽然基于SQL的数据管理系统被广泛使用,键值存储、数据流式处理和MapReduce框架也已经广泛普及。目前需要重新审视整个数据库教学计划。

数据科学

如我们之前所谈到的,大数据需要数据科学家来辅助将大量的数据转换为可以使用的知识。数据科学家不仅仅需要数据管理的知识,也需要商业智能、计算机系统、数学、统计学、机器学习和优化相关的知识。新的跨专业学科项目需要集中这些专业知识。成功的研究和教学需要其他学科和领域专家的辅助。大数据给了计算机科学一个影响化学、地球科学、社会学和其他领域的机会。这些课程中计算机科学的一小部分可以让数据管理和科学扮演一个更加突出的位置。

科研文化

目前一个现象是比起研究成果的影响,人们更加关注论文的引用数量。这就影响了大型项目、端到端工具和数据集分享的实施,因为这通常需要花费更多的时间。太注重偏门学科方向深挖而不注重实际影响的学科团体需要注意一下,发表论文的频率应该回归到更加合理范围,我们应该鼓励大型的系统项目、工具集和数据分享。

向前推进

现在对于数据库研究人员来说真是个令人激动的时代。在以前,数据库研究都限制在企业需求和关系型数据库下。大数据的兴起和大数据驱动时间愿景带来了诸多的挑战:利用新硬件、软件和云平台的潜力;指出数据的生命周期,从数据的产生、分析到分享;面对数据的多样性、在大数据处理各个方面的人物的角色。现在也需要重新审视数据库的教育、数据消费者的演化和我们的价值体系。这对我们评估、传播和资助研究也有很重要的意义。

致谢

感谢审阅者给出的无价建议。Beckman会议是由Ram Kumar Memorial教授的基金会,微软公司和Walmart实验室赞助的

为何要如此努力地增加PT分享率

学校内连接外网的代价还是挺大的,更不要说在线串流电影或是下载了。虽然我没有追剧的压力,看电影的偏好也比较单一,PT的压力不会很大,不过加入北邮人PT后,使用的是全新的账号,由于怕分享率太低被封禁账号,还是需要在下载资源后,利用电脑的空闲资源,在电影看完被删掉前借此增加一点分享率。

理想情况是,电影下好后在观看过程中进行分享,如果一直有较好的上传速度的话,很快就可以流量回本了,无奈几次实验下来,几乎没有分享多少流量,导致分享率已经跌倒了0.1。

大概有这几点原因导致了我分享率很低:

  • 有些我想看的资源已经是冷门资源
  • 我的网络环境太差,其他人从我这获取资源的速度太慢,导致我只能分享他下载流量的很小比例
  • 我一般看完就删,分享时间非常有限
  • PT内网环境中,大家的下载速度都很快,并且有很多人分享,别人在不知道我这里有资源的情况下就已经下载完成了

其中冷门资源想看只能使用其他资源的上传来补了;从我的下载速度可以稳定在10MB/s看来,网络环境不是瓶颈;我并不想囤积电影,看完就删的习惯不准备改变,也不准备话很长时间挂机分享;看来,针对免费的热门资源,如何提高自己的分享效率成为了比较好的方案。

Transmission

Transmission是Linux上很不错的BT下载器,PT资源也支持,它还支持一个Web客户端,Web客户端使用Http与Transmission服务部通信,这就为我们自动话督促分享量提供了机会。

细看Transmission的一个任务,发现其中Peers通常是由Tracker来提供的,但这里显示Transmission每半个小时才会去询问一次有没有更多Peers,这边就带来了可能很多Peers需要下载我分享的资源时候,我并不知道这一情况,错失了很多上传机会。

Transmission

人工通过在任务上右键>Ask Tracker For More Peers刷了几分钟后,发现上传速度能维持在一个不错的水平了。

解决方案

其实就通过查看Web客户端是如何请求Transmission服务器,每隔一段时间强制刷新Peers列表就可以了。

获取Web客户端与Transmission的通信规范

首先通过Transmission>Preferences>Remote>Allow Remote Access打开Web客户端。

Webclient

然后通过Chrome Dev Tools审查Web客户端和服务器的请求。

ChromeDevTools

分析请求发现torrent-get获取任务ID和详情信息,torrent-reannounce向Tracker发出刷新Peers列表的请求。

通过Copy as cURL直接复制Chrome发出的请求,方便进行实验。

通过脚本自动化刷新Peers列表的过程

最终整理Shell脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
while true; do

# 获取Transmission的Session ID,不然后续请求无效
TSID=`curl -sI 'http://localhost:9091/transmission/rpc' |grep -Fi "X-Transmission-Session-Id" | tr -d '\r'`
echo $TSID

# 获取当前任务的ID列表,通过jq工具解析Json
TDATA=`curl -s 'http://localhost:9091/transmission/rpc' -H 'Origin: http://localhost:9091' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4' -H "$TSID" -H 'Content-Type: json' -H 'Accept: application/json, text/javascript, */*; q=0.01' -H 'Referer: http://localhost:9091/transmission/web/' -H 'X-Requested-With: XMLHttpRequest' -H 'DNT: 1' --data-binary '{"method":"torrent-get","arguments":{"fields":["id"],"ids":"recently-active"}}' --compressed | jq -c '{"method":"torrent-reannounce","arguments":{ids: [.arguments.torrents[].id]}}' | tr -d '\r'`
echo $TDATA

# 发出刷新Peers列表的请求
curl 'http://localhost:9091/transmission/rpc' -H 'Origin: http://localhost:9091' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4' -H "$TSID" -H 'Content-Type: json' -H 'Accept: application/json, text/javascript, */*; q=0.01' -H 'Referer: http://localhost:9091/transmission/web/' -H 'X-Requested-With: XMLHttpRequest' -H 'DNT: 1' --data-binary "$TDATA" --compressed

# 每隔一分钟刷新一次
sleep 60
done

其中有一个坑在将一个命令的输出存入Shell变量时候,有时末尾会有’\r’这个字符,但echo这个变量又和不带’\r’的字符串看不出区别。如果不通过tr -d '\r'删除的话,curl发出的请求就不能被正常相应。