首页 文章 精选 留言 我的

精选列表

搜索[分布式锁],共10000篇文章
优秀的个人博客,低调大师

深入浅出:Hadoop的start-balancer.sh与hdfs balancer分布式数据均衡

Hadoop的HDFS集群非常容易出现机器与机器之间磁盘利用率不平衡的情况,比如集群中添加新的数据节点。当HDFS出现不平衡状况的时候,将引发很多问题,比如:1、MR程序无法很好地利用本地计算的优势2、机器之间无法达到更好的网络带宽使用率,机器磁盘无法利用等等。可见,保证HDFS中的数据平衡是非常重要的。在Hadoop中,包含一个Balancer程序,通过运行这个程序,可以使得HDFS集群达到一个平衡的状态,使用这个程序的命令如下: $HADOOP_HOME/bin/start-balancer.sh –t 10% 这个命令中-t参数后面跟的是HDFS达到平衡状态的磁盘使用率偏差值。如果机器与机器之间磁盘使用率偏差小于10%,那么我们就认为HDFS集群已经达到了平衡的状态。Hadoop的开发人员在开发Balancer程序的时候,遵循了以下几点原则:1.在执行数据重分布的过程中,必须保证数据不能出现丢失,不能改变数据的备份数,不能改变每一个rack中所具备的block数量。(这个原则导致了不同rack机柜之间的数据是不能移动的)2.系统管理员可以通过一条命令启动数据重分布程序或者停止数据重分布程序。3.Block在移动的过程中,不能暂用过多的资源,如网络带宽。4.数据重分布程序在执行的过程中,不能影响name node的正常工作。 集群执行balancer依旧不平衡的原因基于这些基本点,目前Hadoop数据重分布程序实现的逻辑流程如下图所示: Name Node <------------------------------->Rebalancing Server<-------------------------------->Proxy source data node /| /|\ | | | | +----------------------------------->destination data node<---------------------------------------+ Rebalance程序作为一个独立的进程与name node进行分开执行。1 Rebalance Server从Name Node中获取所有的Data Node情况:每一个Data Node磁盘使用情况。2 Rebalance Server计算哪些机器需要将数据移动,哪些机器可以接受移动的数据。并且从Name Node中获取需要移动的数据分布情况。3 Rebalance Server计算出来可以将哪一台机器的block移动到另一台机器中去。4,5,6 需要移动block的机器将数据移动的目的机器上去,同时删除自己机器上的block数据。7 Rebalance Server获取到本次数据移动的执行结果,并继续执行这个过程,一直没有数据可以移动或者HDFS集群以及达到了平衡的标准为止。 Hadoop现有的这种Balancer程序工作的方式在绝大多数情况中都是非常适合的。现在我们设想这样一种情况:1 数据是3份备份。2 HDFS由2个rack(机柜)组成。3 2个rack中的机器磁盘配置不同,第一个rack(机柜)中每一台机器的磁盘空间为1TB,第二个rack(机柜)中每一台机器的磁盘空间为10TB。4 现在大多数数据的2份备份都存储在第一个rack(机柜)中。在这样的一种情况下,HDFS级群中的数据肯定是不平衡的。现在我们运行Balancer程序,但是会发现运行结束以后,整个HDFS集群中的数据依旧不平衡:rack1中的磁盘剩余空间远远小于rack2。这是因为Balance程序的开发原则1导致的。简单的说,就是在执行Balancer程序的时候,不会将数据中一个rack(机柜)移动到另一个rack中(机柜),所以就导致了Balancer程序永远无法平衡HDFS集群的情况。针对于这种情况,可以采取2中方案:1 继续使用现有的Balancer程序,但是修改rack中的机器分布。将磁盘空间小的机器分叉到不同的rack中去。2 修改Balancer程序,允许改变每一个rack中所具备的block数量,将磁盘空间告急的rack中存放的block数量减少,或者将其移动到其他磁盘空间富余的rack中去。(不推荐) 1.传输带宽对hdfs负载设置均衡,因为默认的数据传输带宽比较低,可以设置为64M,即hdfs dfsadmin -setBalancerBandwidth 67108864即可 [root@sht-sgmhadoopnn-01 ~# cd /hadoop/hadoop-2.7.2/bin [root@sht-sgmhadoopdn-01 bin# ./hdfs dfsadmin -setBalancerBandwidth 67108864 Balancer bandwidth is set to 67108864 for sht-sgmhadoopnn-01/172.16.101.55:8020 Balancer bandwidth is set to 67108864 for sht-sgmhadoopnn-02/172.16.101.56:8020 2.节点存储使用率偏差默认balancer的threshold为10%,即各个节点存储使用率偏差不超过10%,我们可将其设置为5%;然后启动Balancer,sbin/start-balancer.sh -threshold 5,等待集群自均衡完成即可 [root@sht-sgmhadoopdn-01 bin# cd ../sbin starting balancer, logging to /hadoop/hadoop-2.7.2/logs/hadoop-root-balancer-sht-sgmhadoopnn-01.telenav.cn.out [root@sht-sgmhadoopnn-01 sbin# ./start-balancer.sh -threshold 5 starting balancer, logging to /hadoop/hadoop-2.7.2/logs/hadoop-root-balancer-sht-sgmhadoopnn-01.telenav.cn.out 运行这个命令start-balancer.sh -threshold 5和使用hdfs balancer -threshold 5是一样的 Usage: hdfs balancer [root@sht-sgmhadoopnn-01 bin# ./hdfs balancer -threshold 5 16/03/05 18:57:33 INFO balancer.Balancer: Using a threshold of 1.0 16/03/05 18:57:33 INFO balancer.Balancer: namenodes = [hdfs://mycluster 16/03/05 18:57:33 INFO balancer.Balancer: parameters = Balancer.Parameters[BalancingPolicy.Node, threshold=1.0, max idle iteration = 5, number of nodes to be excluded = 0, number of nodes to be included = 0 Time Stamp Iteration# Bytes Already Moved Bytes Left To Move Bytes Being Moved 16/03/05 18:57:34 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable 16/03/05 18:57:35 INFO net.NetworkTopology: Adding a new node: /default-rack/172.16.101.58:50010 16/03/05 18:57:35 INFO net.NetworkTopology: Adding a new node: /default-rack/172.16.101.60:50010 16/03/05 18:57:35 INFO net.NetworkTopology: Adding a new node: /default-rack/172.16.101.66:50010 16/03/05 18:57:35 INFO net.NetworkTopology: Adding a new node: /default-rack/172.16.101.59:50010 16/03/05 18:57:35 INFO balancer.Balancer: 0 over-utilized: [ 16/03/05 18:57:35 INFO balancer.Balancer: 0 underutilized: [ The cluster is balanced. Exiting... Mar 5, 2016 6:57:35 PM 0 0 B 0 B -1 B Mar 5, 2016 6:57:35 PM Balancing took 2.66 seconds 1).为什么我执行该命令hdfs balancer -threshold 5平衡数据命令没有反应呢?5表示5%, 群总存储使用率: 1.74%sht-sgmhadoopdn-01: 1.74%sht-sgmhadoopdn-02: 1.74%sht-sgmhadoopdn-03: 1.74%sht-sgmhadoopdn-04: 0%执行-threshold 5, 表示每一个 datanode 存储使用率和集群总存储使用率的差值都应该小于这个阀值5%;假如超过5%,会执行数据平衡操作。 B. 2).怎样判断执行命令是否会生效,数据平衡操作? if (群总存储使用率 — 每一台datanode 存储使用率) > -threshold 5 #会执行数据平衡 else #该命令不生效 end ifC. 3).the threshold range of [1.0, 100.0],所以最小只能设置 -threshold 1 D. 4).balance命令可以执行早namenode或者datanode节点上 执行命令hdfs balancer -threshold 2点击(此处)折叠或打开 [root@sht-sgmhadoopnn-01 hadoop# hdfs balancer -threshold 2……………..……………..16/03/08 16:08:09 INFO net.NetworkTopology: Adding a new node: /default-rack/172.16.101.59:5001016/03/08 16:08:09 INFO net.NetworkTopology: Adding a new node: /default-rack/172.16.101.58:5001016/03/08 16:08:09 INFO net.NetworkTopology: Adding a new node: /default-rack/172.16.101.66:5001016/03/08 16:08:09 INFO net.NetworkTopology: Adding a new node: /default-rack/172.16.101.60:5001016/03/08 16:08:09 INFO balancer.Balancer: 0 over-utilized: [16/03/08 16:08:09 INFO balancer.Balancer: 0 underutilized: [The cluster is balanced. Exiting...Mar 8, 2016 4:08:09 PM 1 382.22 MB 0 B -1 BMar 8, 2016 4:08:09 PM Balancing took 6.7001 minutes 新增数据节点的411.7M,偏差小于2%。 start-balancer.sh和stop-balancer.sh的源码解析: [root@sht-sgmhadoopnn-01 sbin]# more start-balancer.sh !/usr/bin/env bash bin=dirname "${BASH_SOURCE-$0}"bin=cd "$bin"; pwdDEFAULT_LIBEXEC_DIR="$bin"/../libexecHADOOP_LIBEXEC_DIR=${HADOOP_LIBEXEC_DIR:-$DEFAULT_LIBEXEC_DIR}. $HADOOP_LIBEXEC_DIR/hdfs-config.sh Start balancer daemon. "$HADOOP_PREFIX"/sbin/hadoop-daemon.sh --config $HADOOP_CONF_DIR --script "$bin"/hdfs start balancer $@解析:start-balancer.sh脚本其实最终还是调用hdfs start balancer $@ 命令,对于 $@ 是指shell脚本运行的传递的参数列表,一般参数为-threshold 5 [root@sht-sgmhadoopnn-01 sbin# more stop-balancer.sh !/usr/bin/env bash bin=dirname "${BASH_SOURCE-$0}"bin=cd "$bin"; pwdDEFAULT_LIBEXEC_DIR="$bin"/../libexecHADOOP_LIBEXEC_DIR=${HADOOP_LIBEXEC_DIR:-$DEFAULT_LIBEXEC_DIR}. $HADOOP_LIBEXEC_DIR/hdfs-config.sh Stop balancer daemon. Run this on the machine where the balancer is running "$HADOOP_PREFIX"/sbin/hadoop-daemon.sh --config $HADOOP_CONF_DIR --script "$bin"/hdfs stop balancer解析:stop-balancer.sh脚本其实最终还是调用hdfs stop balancer命令[root@sht-sgmhadoopnn-01 sbin# 注意事项:由于历史原因,hadoop集群中的机器的磁盘空间的大小各不相同,而HDFS在进行写入操作时,并没有考虑到这种情况,所以随着数据量的逐渐增加,磁盘较小的datanode机器上的磁盘空间很快将被写满,从而触发了报警。此时,不得不手工执行start-balancer.sh来进行balance操作,即使将dfs.balance.bandwidthPerSec 参数设置为10M/s,整个集群达到平衡也需要很长的时间,所以写了个crontab来每天凌晨来执行start-balancer.sh,由于此时集群不平衡的状态还没有那么严重,所以start-balancer.sh很快执行结束了。另外需要注意的地方是,由于HDFS需要启动单独的Rebalance Server来执行Rebalance操作,所以尽量不要在NameNode上执行start-balancer.sh,而是找一台比较空闲的机器。理论参考:http://www.aboutyun.com/thread-7354-1-1.html

优秀的个人博客,低调大师

19、 Python快速开发分布式搜索引擎Scrapy精讲—css选择器

css选择器 1、 2、 3、 ::attr()获取元素属性,css选择器 ::text获取标签文本 举例: extract_first('')获取过滤后的数据,返回字符串,有一个默认参数,也就是如果没有数据默认是什么,一般我们设置为空字符串 extract()获取过滤后的数据,返回字符串列表 #-*-coding:utf-8-*- importscrapy classPachSpider(scrapy.Spider): name='pach' allowed_domains=['blog.jobbole.com'] start_urls=['http://blog.jobbole.com/all-posts/'] defparse(self,response): asd=response.css('.archive-title::text').extract()#这里也可以用extract_first('')获取返回字符串 #print(asd) foriinasd: print(i) 【转载自:http://www.lqkweb.com】

优秀的个人博客,低调大师

阿里毕玄:阿里十年,从分布式到云时代的架构演进之路

编者按:这是一篇来自鲲鹏会的文章,其内容是毕玄在TGO 鲲鹏会杭州分会活动现场分享的《云时代的软件架构》的整理。特别转载到云栖社区,让更多开发者深入了解阿里架构的变迁和对云技术的一些新的想法。 2018 年 12 月 15 日,TGO 鲲鹏会杭州分会拉开了 TGO 特有的技术人年会「E 家宴」的帷幕,60+CTO/ 技术 VP 相聚在杭州殊胜龙井酒店。其中,阿里巴巴系统软件、中间件、研发效能负责人毕玄,连尚网络副总裁 &WiFi 万能钥匙万能接入业务群 CEO、TGO 鲲鹏会上海会员万玉权, 同盾科技联合创始人 & 技术 VP、TGO 鲲鹏会杭州会长张新波,及 TGO 鲲鹏会杭州会员、大搜车技术 VP 沈淦、尚尚签 CTO 陶真,和浪潮集团 AI 首席架构师 张清等重磅嘉宾应邀出席,与参会者一起探讨云时代的软件架构、

优秀的个人博客,低调大师

分布式之数据库和缓存双写一致性方案解析!

一、为什么写这篇文章? 首先,缓存由于其高并发和高性能的特性,已经在项目中被广泛使用。在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作: 但是在更新缓存方面,对于更新完数据库,是更新缓存呢,还是删除缓存?又或者是先删除缓存,再更新数据库?其实大家存在很大的争议。目前没有一篇全面的博客,对这几种方案进行解析,于是博主战战兢兢,顶着被大家喷的风险,写了这篇文章。 二、文章结构 1、讲解缓存更新策略; 2、对每种策略进行缺点分析; 3、针对缺点给出改进方案; 三、正文 先做一个说明,从理论上来说,给缓存设置过期时间,是保证最终一致性的解决方案。这种方案下,我们可以对存入缓存的数据设置过期时间,所有的写操作以数据库为准,对缓存操作只是尽最大努力即可。也就是说如果数据库写成功,缓存更新失败,那么只要到达过期时间,则后面的读请求自然会从数据库中读取新值然后回填缓存。因此,接下来讨论的思路不依赖于给缓存设置过期时间这个方案。在这里,我们讨论三种更新策略: 1、先更新数据库,再更新缓存; 2、先删除缓存,再更新数据库; 3、先更新数据库,再删除缓存; 应该没人问我,为什么没有先更新缓存,再更新数据库这种策略! 四、先更新数据库,再更新缓存 这套方案,大家是普遍反对的,为什么呢?有如下两点原因: 原因一、线程安全角度 同时有请求A和请求B进行更新操作,那么会出现: 线程A更新了数据库; 线程B更新了数据库; 线程B更新了缓存; 线程A更新了缓存; 这就出现请求A更新缓存应该比请求B更新缓存早才对,但是因为网络等原因,B却比A更早更新了缓存。这就导致了脏数据,因此不考虑! 原因二、业务场景角度 有如下两点: (1)如果你是一个写数据库场景比较多,而读数据场景比较少的业务需求,采用这种方案就会导致,数据压根还没读到,缓存就被频繁的更新,浪费性能。 (2)如果你写入数据库的值,并不是直接写入缓存的,而是要经过一系列复杂的计算再写入缓存。那么,每次写入数据库后,都再次计算写入缓存的值,无疑是浪费性能的。显然,删除缓存更为适合。 接下来讨论的就是争议最大的,先删缓存,再更新数据库。还是先更新数据库,再删缓存的问题。 五、先删缓存,再更新数据库 该方案会导致不一致的原因是:同时有一个请求A进行更新操作,另一个请求B进行查询操作。那么会出现如下情形: (1)请求A进行写操作,删除缓存; (2)请求B查询发现缓存不存在; (3)请求B去数据库查询得到旧值; (4)请求B将旧值写入缓存; (5)请求A将新值写入数据库; 上述情况就会导致不一致的情形出现。而且,如果不采用给缓存设置过期时间策略,该数据永远都是脏数据。 那么,如何解决呢?采用延时双删策略!伪代码如下: 转化为中文描述就是: (1)先淘汰缓存; (2)再写数据库(这两步和原来一样); (3)休眠1秒,再次淘汰缓存; 这么做,可以将1秒内所造成的缓存脏数据,再次删除! 5.1、那么,这个1秒怎么确定的,具体该休眠多久呢? 针对上面的情形,读者应该自行评估自己的项目的读数据业务逻辑的耗时。然后写数据的休眠时间则在读数据业务逻辑的耗时基础上,加几百ms即可。这么做的目的,就是确保读请求结束,写请求可以删除读请求造成的缓存脏数据。 5.2、如果你用了MySQL的读写分离架构怎么办? OK,在这种情况下,造成数据不一致的原因如下,还是两个请求,一个请求A进行更新操作,另一个请求B进行查询操作。 (1)请求A进行写操作,删除缓存; (2)请求A将数据写入数据库了; (3)请求B查询缓存发现,缓存没有值; (4)请求B去从库查询,这时,还没有完成主从同步,因此查询到的是旧值; (5)请求B将旧值写入缓存; (6)数据库完成主从同步,从库变为新值; 上述情形,就是数据不一致的原因。还是使用双删延时策略。只是,睡眠时间修改为在主从同步的延时时间基础上,加几百ms。 5.3、采用这种同步淘汰策略,吞吐量降低怎么办? ok,那就将第二次删除作为异步的。自己起一个线程,异步删除。这样,写的请求就不用沉睡一段时间后了,再返回。这么做,加大吞吐量。 5.4、第二次删除,如果删除失败怎么办? 这是个非常好的问题,因为第二次删除失败,就会出现如下情形。还是有两个请求,一个请求A进行更新操作,另一个请求B进行查询操作,为了方便,假设是单库: (1)请求A进行写操作,删除缓存; (2)请求B查询发现缓存不存在; (3)请求B去数据库查询得到旧值; (4)请求B将旧值写入缓存; (5)请求A将新值写入数据库; (6)请求A试图去删除请求B写入对缓存值,结果失败了;ok,这也就是说。如果第二次删除缓存失败,会再次出现缓存和数据库不一致的问题。 5.5、如何解决呢? 具体解决方案,且看博主对第六节更新策略的解析! 六、先更新数据库,再删缓存 首先,先说一下。老外提出了一个缓存更新套路,名为《Cache-Aside pattern》。其中就指出: 失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中; 命中:应用程序从cache中取数据,取到后返回; 更新:先把数据存到数据库中,成功后,再让缓存失效; 另外,知名社交网站facebook也在论文《Scaling Memcache at Facebook》中提出,他们用的也是先更新数据库,再删缓存的策略。 6.1、这种情况不存在并发问题么? 不是的。假设这会有两个请求,一个请求A做查询操作,一个请求B做更新操作,那么会有如下情形产生: (1)缓存刚好失效; (2)请求A查询数据库,得一个旧值; (3)请求B将新值写入数据库; (4)请求B删除缓存; (5)请求A将查到的旧值写入缓存; ok,如果发生上述情况,确实是会发生脏数据。 6.2、然而,发生这种情况的概率又有多少呢? 发生上述情况有一个先天性条件,就是6.1中步骤(3)的写数据库操作比步骤(2)的读数据库操作耗时更短,才有可能使得步骤(4)先于步骤(5)。可是,大家想想,数据库的读操作的速度远快于写操作的(不然做读写分离干嘛,做读写分离的意义就是因为读操作比较快,耗资源少),因此步骤(3)耗时比步骤(2)更短,这一情形很难出现。 假设,有人非要抬杠,有强迫症,一定要解决怎么办? 6.3、如何解决上述并发问题? 首先,给缓存设有效时间是一种方案。其次,采用策略2(先删除缓存,再更新数据库)里给出的异步延时删除策略,保证读请求完成以后,再进行删除操作。 6.4、还有其他造成不一致的原因么? 有的,这也是缓存更新策略2(先删除缓存,再更新数据库)和缓存更新策略3(先更新数据库,再删除缓存)都存在的一个问题,如果删缓存失败了怎么办,那不是会有不一致的情况出现么。比如一个写数据请求,然后写入数据库了,删缓存失败了,这会就出现不一致的情况了。这也是缓存更新策略2(先删除缓存,再更新数据库)里留下的最后一个疑问。 6.5、如何解决? 提供一个保障的重试机制即可,这里给出两套方案。 方案一: 流程如下所示: (1)更新数据库数据; (2)缓存因为种种问题删除失败; (3)将需要删除的key发送至消息队列; (4)自己消费消息,获得需要删除的key; (5)继续重试删除操作,直到成功; 然而,该方案有一个缺点,对业务线代码造成大量的侵入。于是有了方案二,在方案二中,启动一个订阅程序去订阅数据库的binlog,获得需要操作的数据。在应用程序中,另起一段程序,获得这个订阅程序传来的信息,进行删除缓存操作。 方案二: 流程如下图所示: (1)更新数据库数据; (2)数据库会将操作信息写入binlog日志当中; (3)订阅程序提取出所需要的数据以及key; (4)另起一段非业务代码,获得该信息; (5)尝试删除缓存操作,发现删除失败; (6)将这些信息发送至消息队列; (7)重新从消息队列中获得该数据,重试操作; 备注说明:上述的订阅binlog程序在mysql中有现成的中间件叫canal,可以完成订阅binlog日志的功能。至于oracle中,博主目前不知道有没有现成中间件可以使用。另外,重试机制,博主是采用的是消息队列的方式。如果对一致性要求不是很高,直接在程序中另起一个线程,每隔一段时间去重试即可,这些大家可以灵活自由发挥,只是提供一个思路。 七、总结 本文其实是对目前互联网中已有的一致性方案,进行了一个总结。对于先删缓存,再更新数据库的更新策略,还有方案提出维护一个内存队列的方式,博主看了一下,觉得实现异常复杂,没有必要,因此没有必要在文中给出。最后,希望大家有所收获。

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册