阅读更多
本文作者是Gianmario Spacagna和Harry Powell,Barclays的数据科学家。

集群计算和大数据技术已经取得了很多进展,不过现在很多大数据应用使用的还是HDFS这一分布式分件系统。HDFS是一个基于磁盘的文件系统,将数据存储在磁盘上有一些问题,比如说面临法律的监管,由磁盘读写造成的延迟也比较高。要避免这些问题可以将处理过的数据暂时放在内存中。Tachyon就可以帮你让这些数据长期处于内存中并且在不同应用之间共享。

在巴克莱我们并没有把数据存储在HDFS上,而是使用了RDMBS关系型数据库,而且我们还开发了一套让Spark从RDBMS直接读取数据的流程。我们作为读取数据的一方对于数据库的schema并不完全清楚,所以我们先读取为动态类型的Spark DataFrame,分析了数据结构和内容之后再转换为RDD。

这套流程有一个弊端。我们的数据集比较大,所以从RDBMS读取数据要花挺长时间。按理说我们不应该频繁地读取数据,但Spark缓存的数据一崩溃一重启就丢了。这时候就得重新读取数据一次,这么来一次我们的系统就得挂一半个小时,一天重读个几次也是很常见的。哪怕我们做完了数据的映射之后只要运行Spark job也还得重新读取数据,加入新特性,改模型,测试的时候都得这么干。
所以我们找到了Tachyon。Tachyon现在已经改名为Alluxio,它是一个数据存储层,它让所有的Spark应用可以直接通过文件API来读取数据。既方便与现有应用的集成也很简单。

现有架构的问题

如前所述,最主要的问题就是数据的加载。虽然Spark有缓存功能,但当我们重启context,更新依赖或者重新提交job的时候缓存的数据就丢失了,只有从数据库中重新加载这一个办法。

下面的图表是加载数据到6个Spark节点所需要花费的时间(以分钟计)。横坐标代表数据的行数,绿色是晚上六点数据库比较闲的时候,灰色是早晨十点数据库使用率比较高的时候而蓝色是下午两点数据库非常忙的时候。



我们可以看出加载数据的时间从几分钟到几小时不等。考虑到我们一天要重启很多次,光靠Spark的缓存肯定是不够的。我们想要达到的目标有下面三点:

• 缓存DataFrame原始数据用于寻找正确的映射配置
• 缓存RDD用于分析
• 快速读取中间结果并在不同应用之间共享数据
这三点汇成一句话其实就是要一个内存存储系统。

Tachyon

Tachyon不单解决了我们数据存储的问题还将目前的部署速度提升到了一个新台阶。Tachyon作为一种内存分布式文件系统,可以存储任何文本格式或Parquet、Avro和Kryo等高效数据类型。我们还可以将结合进Snappy或LZO等压缩算法来减少对内存的占用。

与Spark应用的集成非常简单,只需调用DataFrame和RDD的加载存储API并指定路径URL和Tachyon协议即可。

我们存储原始数据的目的是快速地迭代探索式分析和测试。现在我们可以直接从原始数据来构建最简可行产品而不必在数据的处理上多花时间。下面是我们部署Tachyon之后的工作流程。



橙色箭头代表我们将数据的中间结果存储到Tachyon以方便以后读取。

Tachyon的配置

在巴克莱我们将Tachyon配置为与tmpfs文件系统配合(unix系统中的路径为/dev/shm)。在Tachyon主节点上的配置由下面五步组成:

1.修改tachyon-env.sh配置文件
export TACHYON_WORKER_MEMORY_SIZE=${TACHYON_WORKER_MEMORY_SIZE:-24GB}

TACHYON_JAVA_OPTS中我们则保留默认配置:
-Dtachyon.worker.tieredstore.level0.
-Dtachyon.worker.tieredstore.level0.dirs.path=${TACHYON_RAM_FOLDER}
-Dtachyon.worker.tieredstore.level0.dirs.quota=${TACHYON_WORKER_MEMORY_SIZE}

2.将配置复制到worker节点中
./bin/tachyon copyDir ./conf/

3.格式化Tachyon
./bin/tachyon format

4.部署Tachyon。注意NoMount选项,NoMount不需要root权限:
./bin/tachyon-start.sh all NoMount

下面是我们整个架构的示意图:



Tachyon与Spark的结合使用

Tachyon中数据的读写非常简单,因为它所提供的文件API与Java类似。往Tachyon中写DataFrame:
dataframe.write.save("tachyon://master_ip:port/mydata/mydataframe.parquet")

从Tachyon中读取DataFrame:
val dataframe: DataFrame = sqlContext.read.load("tachyon://master_ip:port/mydata/mydataframe.parquet")

写入RDD:
rdd.saveAsObjectFile("tachyon://master_ip:port/mydata/myrdd.object")

读取RDD:
val rdd: RDD[MyCaseClass] = sc.objectFile[MyCaseClass] ("tachyon://master_ip:port/mydata/myrdd.object")

这里要注意MyCaseClass的类型必须与写入时一致,不然会出错。

效果

我们使用Spark、Scala、DataFrame、JDBC、Parquet、Kryo和Tachyon创建出了一套数据项目流程,它具有扩展性好和速度快等优点,质量也足以直接部署到生产环境中。

Tachyon使我们能够直接读取原始数据而不必从数据库中加载。数据写入Tachyon之后也可以迅速开始分析,提高了工作的效率。

使用Tachyon将数据存储在内存中读写只需几秒钟,所以在我们的流程中扩展几乎不影响性能。迭代一次所需的时间从以前的几个小时降低到了现在的几秒钟。

未来展望

Tachyon自身还在发展,我们对Tachyon的使用也还在进一步的探索中,所以有一些限制是难免的。下面我们就列出了一些还有待提高的地方。
• 我们没有指定底层的存储设备所以Tachyon所能够存储的数据量受到所分配空间的限制。Tachyon提供了分层存储功能来解决这个问题。
• 设置JDBC驱动、分区策略和类映射还比较麻烦而且不够易用。
• Spark和Tachyon共享内存,所以为了避免重复和过度的垃圾回收还需要做一些调整。
• 如果Tachyon worker挂了,数据就会丢失。因为我们没有使用分层存储所以Tachyon自己不会重新加载数据。对巴克莱来说还好但对于其他企业来说可能还需要进一步的改进。

总的来说我们还是很看好Tachyon,它应该会对企业中的数据项目有所影响。

原文链接:Making the Impossible Possible with Tachyon: Accelerate Spark Jobs from Hours to Seconds
  • 大小: 64.5 KB
  • 大小: 72.4 KB
  • 大小: 88.3 KB
1
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 常用JS脚本页面判断

    一、验证类 1、数字验证内 1.1 整数 1.2 大于0的整数 (用于传来的ID的验证) 1.3 负整数的验证 1.4 整数不能大于iMax 1.5 整数不能小于iMin 2、时间类 2.1 短时间,形如 (13:04:06) 2.2 短日期,形如 (2003-12-05) 2.3 长时间,形如 (2003-12-05 13:04:06) 2.4 只有年和月。形如(2003-05,或者2003-5) 2.5 只有小时和分钟,形如(12:03) 3、表单类 3.1 所有的表单的值都不能为空 3.2 多行文本框的值不能为空。 3.3 多行文本框的值不能超过sMaxStrleng 3.4 多行文本框的值不能少于sMixStrleng 3.5 判断单选框是否选择。 3.6 判断复选框是否选择. 3.7 复选框的全选,多选,全不选,反选 3.8 文件上传过程中判断文件类型 4、字符类 4.1 判断字符全部由a-Z或者是A-Z的字字母组成 4.2 判断字符由字母和数字组成。 4.3 判断字符由字母和数字,下划线,点号组成.且开头的只能是下划线和字母 4.4 字符串替换函数.Replace(); 5、浏览器类 5.1 判断浏览器的类型 5.2 判断ie的版本 5.3 判断客户端的分辨率 6、结合类 6.1 email的判断。 6.2 手机号码的验证 6.3 身份证的验证 二、功能类 1、时间与相关控件类 1.1 日历 1.2 时间控件 1.3 万年历 1.4 显示动态显示时钟效果(文本,如OA中时间) 1.5 显示动态显示时钟效果 (图像,像手表) 2、表单类 2.1 自动生成表单 2.2 动态添加,修改,删除下拉框中的元素 2.3 可以输入内容的下拉框 2.4 多行文本框中只能输入iMax文字。如果多输入了,自动减少到iMax个文字(多用于短信发送) 3、打印类 3.1 打印控件 4、事件类 4.1 屏蔽右键 4.2 屏蔽所有功能键 4.3 和<-- F5 F11,F9,F1 4.4 屏蔽组合键ctrl+N 5、网页设计类 5.1 连续滚动的文字,图片(注意是连续的,两段文字和图片中没有空白出现) 5.2 html编辑控件类 5.3 颜色选取框控件 5.4 下拉菜单 5.5 两层或多层次的下拉菜单 5.6 仿IE菜单的按钮。(效果如rongshuxa.com的导航栏目) 5.7 状态栏,title栏的动态效果(例子很多,可以研究一下) 5.8 双击后,网页自动滚屏 6、树型结构。 6.1 asp+SQL版 6.2 asp+xml+sql版 6.3 java+sql或者java+sql+xml 7、无边框效果的制作 8、连动下拉框技术

  • js判定是否首页进入页面

    可以在某一页面,通过localStorage存储指定key,并通过key值判断是否首次进入该页面 具体如下: 1 定义页面key值和对应的value值 // key值自定义,无特殊要求,只作为判断的依据 const key = YOUR_PAGE_NAME // 这里写入的key值为当日时间,可以确保第二天时依然能够进行首次判定 const date = new Date().toDateString() 2 通过getItem获取key值 用来判定value是否存在、是否改变,以此判定是否为当日首次

  • Auto.js实现返回到应用首页(判断是否在应用首页)

    Auto.js使用实现模拟点击过程中,有时软件并不在脚本运行页面,使得脚本运行无效。例如脚本需要在软件首页才能找到相关元素实现模拟操作,就需要判断页面状态,不是首页返回到首页,是首页运行脚本。......

  • 页面上的javascript判断

    经过一段时间的编程,感觉这些javascript比较长用所以就整理了一下,其中有判断是否为空,判断数字,判断金额,及判断时间的。像那些可以写到js中,这样就在页面上简化了好多了。 无标题文档去掉空格function Trim(str){ if(str.charAt(0) == " "){  str = str.slice(1);  str = Trim(str);  } return st

  • js 判断html对象的样式,JS获取三种CSS样式的方法

    一、获取元素的行内样式varobj=document.getElementById("test");alert(obj.height+"\n"+obj.width);//200px200pxtypeof=string只是将style属性中的值显示出来二、获取计算后的样式varobj=document.getElementById("test");varstyl...

  • html判断输出,C# Razor输出javascript 前端cshtml判断输出ViewBag

    开始遇到这个问题,是源于ViewBag的一个值是个对象类型。 假设是User{ id="1",name="test"} 这样的结构。那在前端就有可能出现ViewBag.User为null的情况。为了解决这个问题,查找资料,给出的答案是@{if(ViewBag.User==null){}}但这样有个问题,既然已经变成了后台代码,怎么输出前端代码呢?于是继续寻找答案,找到了这样的代码@if(View...

  • 怎么在html中写js判断语句,javascript如何使用if语句?

    JavaScript中的if可实现条件分支也就是条件语句,所以,接下来的这篇文章就来给大家介绍关于JavaScript中if条件语句的用法,有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。条件语句用于基于不同条件执行不同的动作。在 JavaScript 中,我们可使用如下条件语句:使用 if 来规定要执行的代码块,如果指定条件为 true使用 else 来规定要执行的代码块,如果相...

  • JS判断是否是首页 ,404页

    /* 判断是否是首页*/function isHomePage(){ var localUrl = window.location.href; var regex = new RegExp("^https?://(test-)?www\.4008000000.com(/?|/index[(.|_)].*|/?[?].*)$", "i"); return regex.tes...

  • js判断当前页面是否活动页面

    在开发中,希望当前页面如果不是活动页面,即用户切换了tab页,或者用户把浏览器缩小隐藏了 这个时候,我们希望页面暂停,比如游戏暂停,视频停止播放等。 那怎么做呢? 1、使用document.hidden来判定是否隐藏 var hidden, state, visibilityChange; if (typeof document.hidden !== "undefined") { h...

  • js判断页面是否登录

    Object gv_currentuser = session.getAttribute("WUser");   %>   //初始化  common.js 定义的一些全局变量 gv_BasePath = ""; var WUser    =""; if(WUser == 'null'){ alert("未登录系统"); window.location.href=gv_Ba

  • js 怎样判断用户是否在浏览当前页面

    有些时候我们需要在项目中判断用户是否在浏览当前页面,或者当前页面是否处于激活状态。然后再进行相关的操作。浏览器中可通过window对象的onblur、onfocus判断,或者document的hidden属性判断。 1、window.onblur &amp; window.onfocus 关于是否失焦点,浏览器对象有onfocus和onblur事件可以监听。但是触发这两个事件的前...

  • 原生Js判断当前页面是否是第一次打开

    原理是利用浏览器cook来判断,当当前页面不存在cook时就是第一次打开 代码:  function Cookie(key,value){ this.key=key; if(value!=null) { this.value=escape(value); } this.expiresTime=null; this.do

  • js判断当前页面是不是第一次被访问

        if(document.cookie.indexOf(&quot;a=hello&quot;)==-1){        alert(&quot;首次打开!&quot;);        var t=new Date(new Date().getTime()+1000*60*60*24*30);        document.cookie=&quot;a=hello; expires=&quot;+t.toGMTString();    }els...

  • javascript 页面输入内容的检查与判断方法

    String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); } function lockNumber() { var str="0123456789"; for (i=0;i<10;i++) { if(window.event.keyCode ==str.charCodeAt(i

  • js判断用户有没有操作页面

    用js判断用户有没有操作页面,我们所要做的就是整理我们的思路。一、思路用户有没有操作界面,我们可以从页面在规定时间内有没有触发事件去考虑。比如用户有没有点击,有没有按键,有没有滚动鼠标滚轴。用户有没有移动鼠标等等。如果用户没有进行这些操作,那么我们可以大概的认为用户没有操作页面。我们可以给一个定时器。来记录在规定时间内用户有没有触发这些事件。我直接贴代码,代码的具体含义,我就不再讲解,思路大概就是这

  • javascript里面的if条件判断,==比较和页面刷新跳转

    目录 1 if条件判断 2==(相等)与===(全等) 2.1 基础类型比较 2.2 高级对象类型比较 2.3基础类型和高级类型进行比较 2.4 特例 3页面刷新跳转 3.1 页面刷新 3.1.1 方法刷新 3.1.2 其他方法刷新 3.1.3 页面刷新 3.2 跳转 3.2.1 跳转方法 3.2.2 href=javascript:void(0); 1 if条件判断 在JS中,If 除了能够判断bool的真假外,还能够判断一个变量是否有值。 变量值 t...

  • js检测关闭页面或浏览器

    使用onunload 或 onbeforeunload 事件监听

  • js判断第一次打开页面

    if(!window.name) { //console.log("第一次打开"); window.name = "myname" //第一次打开时设置name localStorage.clear(); //清全部缓存 }

Global site tag (gtag.js) - Google Analytics