文章目录
近年来,云计算越来越流行,企业从自身利益出发,或是不愿意被单一云服务商锁定,或是业务和数据冗余,或是出于成本优化考虑,会尝试将部分或者全部业务从线下机房迁移到云或者从一个云平台迁移到另一个云平台。
本期跟大家分享我在使用Juicesync工具实现对腾讯云CHDFS存储的数据迁移的实验过程及思路。
Juicesync是一个用来拷贝任意云以及地域对象存储数据的工具,它同样支持本地文件,SFTP,HDFS等系统。
这个工具的代码和 juicefs sync 代码相同,Juicesync代码基本引用 juicefs sync部分的代码。
官网:https://juicefs.com/
GitHub:https://github.com/juicedata/juicesync
这个工具不依赖于Juicefs文件系统,可以进行单独使用,并且可以用作于跨云,跨平台,跨地域进行对象数据的迁移复制等场景。
此工具可以支持以下存储:

本次我们的目的就是尝试使用Juicesync工具,进行对腾讯云CHDFS存储的数据迁移。
· 环境:Linux x86_64 centos7.6
Step1:下载地址:
https://github.com/juicedata/juicesync/releases
在地址中选择对应的系统版本,使用命令下载压缩包 ⬇
wget:https://github.com/juicedata/juicesync/releases/download/v1.0.2/juicesync_1.0.2_Linux_x86_64.tar.gz
Step2:解压:
tar -zxvf juicesync_1.0.0_Linux_x86_64.tar.gz
Step3:配置
mv juicesync /usr/local/bin

由于在实践过程中,我们需要在 Hadoop 的环境中hdf数据来实现,所以先讲一讲 Haddop系统(本次主要不对细节做介绍,主要介绍整体结构以及服务)。
Haddop系统本身并不是一个单一的系统,而是由3个系统共同组成:HDFS(分布式文件系统),YARN(分布式资源调度系统),MapReduce(分布式计算系统)。
而这3个系统又分别由不同的服务组成:HDFS(分布式文件系统),YARN(分布式资源调度系统),MapReduce(分布式计算系统);
· Hadoop HDFS 分布式文件系统
NameNode:管理元数据(fsimage) ,文件属性,节点属性,文件在哪些节点
DataNode:存储数据,文件块,block 128M 心跳(状态,资源信息)
SecondaryNameNode :合并元数据信息,fsimage—>NameNode
· Hadoop MapReduce 分布式计算系统
JobTracker:作业的管理和调度、资源分配
TaskTracker:作业的具体执行,发送心跳机制JobTracker汇报
MapTask :Mapper.map() 执行用户自定的map函数
ReduceTask:Reduce.reduce() 执行用户自定义的reduce函数
· Hadoop Yarn 分布式资源管理系统
ResourceManager:资源调度,管理集群中所有的物理机(内存、计算资源)
NodeManager:当前物理机上的管理者,用来创建具体执行任务进程。
由于最终目的是对CHDFS 数据迁移,所以为了适配CHDFS,这里选择在腾讯云的 CVM 上进行安装。
因为 CHDFS 只能支持同VPC网络内,通过同地域访问CHDFS。

Step1: 准备
Java环境:

Step2:下载hadoop压缩包
地址:
https://www.apache.org/dyn/closer.cgi/hadoop/common/hadoop-2.8.5/hadoop-2.8.5.tar.gz
wget https://archive.apache.org/dist/hadoop/common/hadoop-2.8.5/hadoop-2.8.5.tar.gz
Step3:解压
mv hadoop-2.8.5.tar.gz /data/
cd /datatar -zxvf
hadoop-2.8.5.tar.gz

Step4:修改hadoop配置
修改Hadoop安装目录下 etc/haddop 下的 haddop-env.sh
指定 java_home 到具体目录。

修改Hadoop安装目录下的 etc/hadoop 下的 core-site.xml
<configuration>
<!-- 指定HDFS老大(namenode)的通信地址 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://服务器的真实ip:9002</value>
</property>
<!-- 指定hadoop运行时产生文件的存储路径 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/data/hadoop/tmp</value>
</property>
</configuration>

修改Hadoop安装目录下 etc/hadoop 下的 hdfs-site.xml 内容
<configuration>
<property>
<name>dfs.namenode.name.dir</name>
<value>/data/hadoop/hadoop/hdfs/nn</value>
</property>
<property>
<name>fs.checkpoint.dir</name>
<value>/data/hadoop/hdfs/snn</value>
</property>
<property>
<name>fs.checkpoint.edits.dir</name>
<value>/data/hadoop/hdfs/snn</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/data/hadoop/hdfs/dn</value>
</property>
<property>
<name>dfs.name.dir</name>
<value>/data/hadoop/name</value>
</property>
<property>
<name>dfs.data.dir</name>
<value>/data/hadoop/node</value>
</property>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.http.address</name>
<value>服务器的真实ip:9000</value>
</property>
<property>
<name>ipc.maximum.data.length</name>
<value>134217728</value>
</property>
</configuration>


修改Hadoop安装目录下 etc/hadoop 下的 yarn-site.xml 内容
<configuration>
<!-- Site specific YARN configuration properties -->
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.application.classpath</name>
<value>
/data/hadoop-2.8.5/etc/*,
/data/hadoop-2.8.5/etc/hadoop/*,
/data/hadoop-2.8.5/lib/*,
/data/hadoop-2.8.5/share/hadoop/common/*,
/data/hadoop-2.8.5/share/hadoop/common/lib/*,
/data/hadoop-2.8.5/share/hadoop/mapreduce/*,
/data/hadoop-2.8.5/share/hadoop/mapreduce/lib/*,
/data/hadoop-2.8.5/share/hadoop/hdfs/*,
/data/hadoop-2.8.5/share/hadoop/hdfs/lib/*,
/data/hadoop-2.8.5/share/hadoop/yarn/*,
/data/hadoop-2.8.5/share/hadoop/yarn/lib/*
</value>
</property>
</configuration>

Step4:配置免密登录
1)到 root 目录下:cd /root
2——执行生成密钥命令:ssh-keygen -t rsa
3)然后三个回车
4)复制公钥追加到第一台节点的公钥文件中:
ssh-copy-id -i /root/.ssh/id_rsa.pub root@master01
5)选择 yes
6)输入登录第一台节点的密码(操作完成该节点公钥复制到第一台节点中)
Step5:配置环境变量

Step6:初始化节点
执行Hadoop目录下的bin/hdfs
./bin/hdfs namenode -format
Step7:安装
执行Hadoop安装目录下的sbin执行start-all.sh
.sbin/start-all.sh
使用jps验证是否安装成功。

执行Haddop命令验证

云HDFS(Cloud HDFS,简称:CHDFS)是腾讯云一种提供标准HDFS访问协议、卓越性能、分层命名空间的分布式文件系统。
本次实践的目的就是尝试使用Juicesync工具实现对腾讯云CHDFS存储的数据迁移。
使用 Juicesync 尝试对接 CHDFS:


我们发现,并不像预想的一样,可以直接对接。
这里的ofs串是腾讯云CHDFS的挂载点,并不能直接作为hdfs串来使用,因为Juicesync工具不能识别这个串。
但是如果将ofs换为hdfs,也不能使用。因为后边的域名Juicesync无法解析。
那么尝试手动解析域名,然后再尝试,可以发现程序直接发生了panic。

通过查看Juicesync源码发现,Juicesync这里连接HDFS是通过colinmarc/hdfs包实现的。

猜测有可能是HDFS包使用的时候,有默认配置,导致的无法连接或者报错。这里编写go程序来使用HDFS包。

连接本地HDFS
这里尝试连接本地的HDFS服务,并获取 test/text.txt 的内容。

然后,将连接地址改为CHDFS挂载点解析后的IP。

现在连接的时候,可以连接成功,但是仍然panic。
通过查看HDFS包的代码,可以发现HDFS包连接HDFS服务的方式,是通过RPC的方式来连接Hadoop HDFS 的Namenode的。


通过文献查询以及查看Hadoop的源码,可以了解到Hadoop的命令行与HDFS命令进行调用也是通过与Namenode通过RPC的方式。
Hadoop 中是在 Hadoop 项目的 hadoop-common 中src/main/java/org/apache/haddop 中的 fs 中的FsShell.java 中的 main 函数作为 hadoop fs 命令的入口。


这里先调用ToolRunner.run;

再调用到tool.run,即FsShell.run。

那么,同样是通过RPC的方式,为什么一个可以,另一个不可以?
这里推测是CHDFS的问题。
还有一种可能就是命令行的RPC调用层级高于HDFS,即命令行调用了RPC的时候,在Namenode内部,仍然执行了在挂载CHDFS的JAR包逻辑,而HDFS包则没有执行这部分逻辑。
通过上边的推断,实现 Juicesync 调用 CHDFS 的思路就是查看 Hadoop 的 FsShell.java 部分的代码。
以此来查看命令行是通过哪个RPC接口来进行调用的,并将对应的proto文件拷贝到HDFS包内,然后通过 protobuf 命令来生成go文件,从而来调用与FsShell.java部分相同的RPC接口来实现仿照命令行的RPC调用,最终来实现对CHDFS的操作。
以上就是本期关于使用Juicesync工具实现对腾讯云CHDFS存储的数据迁移全部思考实现的过程啦~如果你更好的思路,欢迎跟我们留言分享。
说明:文章由神州数码武汉云基地团队实践整理输出,转载请注明出处。
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h