这篇文章给大家聊聊关于contains怎么读,以及phrases怎么读对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。
other与any other的区别
区别是:意思不同、用法不同、侧重点不同
1、anyother的意思是:其他的;任何其他的;其他任何一个
例句:
Theywerejustlikeanyotheryoungcouple
他们同别的年轻夫妇没什么两样。
2、other的意思是:另外;其他;(指两个人或事物中的第二个)那个,另一个;其余的,另外的
例句:
Youdeliberatelywentintheotherdirection
你故意朝另一个方向走。
二、用法不同
1、anyother:后一般即可跟可数名词复数,也可跟可数名词单数,但是在“thananyother”结构中,如果前面的主语是单数,后面的被比较对象只用单数,如果在“thananyother”结构中,主语是复数,则anyother+复数形式。
2、other:表特指时其前用定冠词,表泛指时其前不用冠词;用于单数时后接单数名词或不接词(即用作代词),用于复数时后接复数名词或用others这样的形式。
三、侧重点不同
1、anyother侧重指在同一范围内除了某人或某物以外的其他人或事物。
2、Other侧重于表示与已经指定或已知的人或事物不同的人或事物。
line contains null byte什么意思
空行。
空读空气的空。意思是这行什么都没有。null是“无”。
nullbyte,ASCII码0称为null字符。字符串结束符就是'\0'。
spark中的广播变量是怎么设计和实现的
Spark官网上对广播变量的描述:
Broadcastvariablesallowtheprogrammertokeeparead-onlyvariablecachedoneachmachineratherthanshippingacopyofitwithtasks.Theycanbeused,forexample,togiveeverynodeacopyofalargeinputdatasetinanefficientmanner.Sparkalsoattemptstodistributebroadcastvariablesusingefficientbroadcastalgorithmstoreducecommunicationcost.
大意是,使用广播变量,每个Executor的内存中,只驻留一份变量副本,而不是对每个task都传输一次大变量,省了很多的网络传输,对性能提升具有很大帮助,而且会通过高效的广播算法来减少传输代价。
使用广播变量的场景很多,我们都知道spark一种常见的优化方式就是小表广播,使用mapjoin来代替reducejoin,我们通过把小的数据集广播到各个节点上,节省了一次特别expensive的shuffle操作。
比如driver上有一张数据量很小的表,其他节点上的task都需要lookup这张表,那么driver可以先把这张表copy到这些节点,这样task就可以在本地查表了。
今天我们来看下Spark对广播变量的设计和实现。
Spark广播的方式:
Spark历史上采用了两种广播的方式,一种是通过Http协议传输数据,一种是通过Torrent协议来传输数据,但是最新的spark版本中,http的方式已经废弃了(pr在此https://github.com/apache/spark/pull/10531),spark是在spark1.1版本中引入了TorrentBroadcast,此后就没有更新HttpBroadcast和相关文档了,spark2.0的时候完全可以删除HttpBroadcast了,之后统一把TorrentBroadcast作为广播变量的唯一实现方式。但是代码没有写死,还是保留了扩展性(BroadcastFactory作为一个trait,TorrentBroadcastFactory只是一种实现方式,符合依赖倒置原则,依赖抽象,不依赖具体实现),万一之后想到了更牛x的实现方式,可以方便的加上,但是我估计一时半会应该没有了。
本着过时不讲的原则,我们这里只说TorrentBroadcast,大家可以到这里看下动图。
http://mg8.org/processing/bt.html
你能看到不同的数据块是来自不同的节点,多个节点一起组成一个网络,在你下载的同时,你也在上传,所以说在享受别人提供的下载的同时,你也在贡献,最终所有人一起受益。
们看下BitTorrent协议,wiki定义:
BitTorrent协议(简称BT,俗称比特洪流、BT下载)是用在对等网络中文件分享的网络协议程序。和点对点(point-to-point)的协议程序不同,它是用户群对用户群(peer-to-peer),而且用户越多,下载同一文件的人越多,下载该档案的速度越快。且下载后,继续维持上传的状态,就可以“分享”,成为其用户端节点下载的种子文件(.torrent),同时上传及下载。
具体感兴趣的可以看下这个论文。
http://www.webpaas.com/usr/uploads/2015/01/52279564.pdf
关键的几个点:
下载者要下载文件内容,需要先得到相应的种子文件,然后使用BT客户端软件进行下载。
提供下载的文件虚拟分成大小相等的块,并把每个块的索引信息和Hash验证码写入种子文件中
有一个Tracker负责维护元信息,所有的客户端都可以通过Tracker找到每个快离自己最近的其他下载者
下载时,BT客户端首先解析种子文件得到Tracker地址,然后连接Tracker服务器。Tracker服务器回应下载者的请求,提供下载者其他下载者(包括发布者)的IP。下载者再连接其他下载者,根据种子文件,两者分别告知对方自己已经有的块,然后交换对方所没有的数据。此时不需要其他服务器参与,分散了单个线路上的数据流量,因此减轻了服务器负担。
下载者每得到一个块,需要算出下载块的Hash验证码与种子文件中的对比,如果一样则说明块正确,不一样则需要重新下载这个块。这种规定是为了解决下载内容准确性的问题。
针对以上的几个点,spark是怎么做的,我们看下:
TorrentBroadcast底层使用的是BlockManager,下载每个数据块先要去master去获取Block所在的位置(location)。
在把大变量写到广播变量的时候,通过ChunkedByteBufferOutputStream把输入的数据分成多个小块,zipWithIndex中,为每个小块加一个唯一标识,形如broadcast_broadcastId_pieceId。作为BlockId,存储在BlockManager中。而且对每个小的数据块加上一个校验码。
BlockManagerMaster作为tracker维护所有Block块的元信息,知道每个数据块所在的executor和存储级别。Broadcast变量中维护属于自己的所有小块的BlockId
通过value方法读取Boradcast变量的时候,取出所有小块的BlockId,对于每个BlockId,通过BlockManagerMaster获取了该BlockId的位置的集合,随机化,位置集合被打乱,优先找同主机的地址(这样可以走回环),然后从随机的地址集合按顺序取地址一个一个尝试去获取数据,因为随机化了地址,那么executor不只会从Driver去获取数据。分散了driver上的压力。
取到Blockpiece后,使用校验码进行校验,看看数据块有没有损坏,如果没有损坏,然后按照顺序拼在一起。
大家比较一下,流程是不是差不多,基本贯穿了BitTorrent的思想原理。
开始的时候,大家都是通过driver拿数据,但是一旦其他executor上有了数据块之后,所有的executor都是有机会通过别的executor来获取数据块,这样就分散了driver的压力。套用一句话,下载的executor越多,下载的越快。
Spark广播变量的使用姿势:
valarray:Array[Int]=???
valbroadcasted=sc.broadcast(array)
valrdd:RDD[Int]=???
rdd.map(i=>array.contains(i))//这种没有使用broadcast,每次task都要传一下数组,浪费内网带宽
rdd.map(i=>broadcasted.value.contains(i))
上面的一个小的demo就是把一个数组通过broadcast的方式广播出去,然后就可以在task里面使用数组变量了,这个数组变量是驻留在executor上的,不用每次调度task运行的时候都得传输一次数组。
我们可以看到对于broadcast的使用,无非就是sc.broadcast定义了一个广播变量和broadcasted.value使用广播变量的value方法,找到真正的数组。
sparkcontext初始化的时候,sparkEnv中初始化了一个broadcastManager,初始化方法里面,现在默认使用的TorrentBroadcastFactory,调用sc.broadcast方法,就会使用工厂模式创建一个TorrentBroadcast,这时候就会调用写操作,把数据分成小块写到BlockManager中,broadcasted只是一个TorrentBroadcast类型的实例,并没有数组数据,这个实例只维护了数据的元信息,也就是一组BlockId信息,这个实例被序列化被传到executor上,在executor上调用这个实例的value方法,才会触发去BlockManager上读真正的数据。
广播变量的回收:
在调用sc.Broadcast方法中,会去ContextCleaner中注册一下,之前讲的缓存RDD的时候也要去ContextCleaner中注册一下,两个差不多,都是为了回收。
cleaner.foreach(_.registerBroadcastForCleanup(bc))
当广播变量引用为null的时候,在contextcleaner里面会回调broadcastManager.unbroadcast方法,会把Broadcast变量从BlockManager存储中干掉。
为什么只能broadcast只读的变量:
这就涉及一致性的问题,如果变量可以被更新,那么一旦变量被某个节点更新,其他节点要不要一块更新?如果多个节点同时在更新,更新顺序是什么?怎么做同步?仔细想一下,每个都很头疼,spark目前就索性搞成了只读的。因为分布式强一致性真的很蛋疼。
vt.是什么词性的词
vt.是及物动词词性的词。
英语动词有及物(transitiveverb)与不及物(intransitiveverb)之分。及物,顾名思义就是涉及到它物的意思,类似汉语中的它动词,不及物就是不涉及到它物的意思,类似汉语中的自动词。
及物动词
后面必须跟宾语意义才完整的实义动词,叫做及物动词(transitiveverb)。有的动词必须接一个宾语,有的必须接两个宾语。如:
He'sreadingamagazine.他正在读一本杂志。
Crudeoilcontainsmanyusefulsubstances.原油含有许多有用的物质。
关于本次contains怎么读和phrases怎么读的问题分享到这里就结束了,如果解决了您的问题,我们非常高兴。