کم و زیاد کردن نود در هادوپ و RACK AWARENESS بودن و HA ؛ آشنایی با SQOOP

جلسه هفتم: 1400/05/10

چند دستور لینوکسی:
Rack Awareness چیست؟  برای بالابردن تحمل خرابی لازم است تا داده ها را میان نودهای مختلف تقسیم کنیم. بطور مثال بافرض replication=3 و در اختیار داشتن 3 رک خوب است که 3 نود حاوی داده ها برروی 3 رک مختلف قرار گیرد. مشکلی که در این بین به وجود می آید کاهش کارایی بخاطر ارتباط کند بین رک ها می باشد. آنچه که هادوپ انجام می دهد آن است که میانه را درنظر گرفته؛ یعنی 2 نود از یک رک و 1 نود از رک دیگر را برای ذخیره سازی اطلاعات درنظر می گیرد؛ هم کارایی و هم تحمل پذیری خطا. 
پیاده سازی Rack Awareness 
- ابتدا در مسیر اصلی هادوپ فولدری با عنوان conf ساخته شود
- فایلی با عنوان topology.data را در مسیری که ایجاد شده کپی می نماییم. کل محتویات این فایل به شرح زیر است. همانگونه که مشخص است، رک مرتبط با هر نود مشخص شده است.
192.168.56.10 rack0
192.168.56.11 rack1
192.168.56.12 rack2
- فایل دیگری را هم که در مسیر قرار می دهیمtopology.sh است. وظیفه این فایل خواندن topology.data و در مقابل پاس دادن ادرس یک نود مشخص می کند که نود مربوطه در کدام رک قرار دارد. در ادامه به topology.sh دسترسی execute خواهیم داد.
chmod +x /opt/hadoop/etc/hadoop/conf/topology.sh
- حالا برای استفاده از topology.sh کافیست که به شکل نمونه به ترتیب زیر عمل کنید
 /opt/hadoop/etc/hadoop/conf/topology.sh 192.168.56.10
- و درمقابل پیام زیر مبنی بر رک مرتبط با آدرس ارائه شده را دریافت می کنید
/default/rack_rack2  
نکته: درصورتیکه هنگام اجرا topology.sh پیام نامرتبط no such directory دریافت کردید لازم است تا این فایل را حذف نموده و با دستور vim ایجاد و در ادامه متن آن را از محیط ویندوز کپی و در محیط vim کپی نمایید. احتمالا این مشکلی ناشی از وجود کاراکترهای encoding ویندوزی باشد. درصورتیکه مشکل باقی ماند فایل topology.data را حذف و مجددا با دستور vim ایجاد کنید.
- در ادامه برای آگاه ساختن hdfs از وجود فایل تخصیص رک به سرورها مقادیر زیر را در فایل core-site.xml تنظیم نمایید.
<property>
<name>net.topology.script.file.name</name>
<value>/opt/hadoop/etc/hadoop/conf/topology.sh</value>
</property>
<property>
<name>net.topology.script.number.args</name>
<value>50</value>
</property>
- فایل core-site.xml را برروی سایر سرورها نیز کپی نمایید.
- جهت موثر بودن این تنظیمات لازم است تا سرویس hdfs-dfs استاپ و استارت شود.
نکته: درصورتیکه Replication Factor=1 باشد، تنظیمات رک تغییری در بالابردن تحمل پذیری نخواهد کرد.
نکته: برای کنترل اثر تغییرات انجام شده در hdfs کافی است تا دستور زیر را اجرا نمایید.
hdfs dfsadmin -report
-مثالی از گزارش سیستم با اجرای دستور بالا در زیر آمده است
Name: 192.168.56.12:9866 (node2)
Hostname: node2
Rack: /default/rack_rack2
- همچنین میتوان با اجرای دستور زیر، به نتیجه ی مشابه دست یافت
hdfs dfsadmin -printTopology
Rack: /default/rack_rack1
   192.168.56.11:9866 (node1)

Rack: /default/rack_rack2
   192.168.56.12:9866 (node2)

اضافه و کم کردن نود: 
- یک را ه برای اضافه کردن نود آنست که VM مربوط به نود را استاپ و سپس از آن clone کنیم. در ادامه لازم است تا مسیر data نود جدید تخلیه شود. /opt/data
- برای اضافه  کردن نود کافیست تا در مسیر /opt/hadoop/etc/hadoop/ فایلی تحت عنوان dfs.include ساخته و در هر سطر آن به نام یک نود اشاره کنیم.
- برای کم  کردن نود کافیست تا در مسیر /opt/hadoop/etc/hadoop/ فایلی تحت عنوان dfs.exclude ساخته و در هر سطر آن به نام یک نود اشاره کنیم.
- درنهایت باید دستور زیر را اجرا کرد
hdfs dfsadmin -refreshNamenodes
پیاده سازی High Availability:
وضعیتی را درنظر بگیرید که NN (resource manager) در دسترس نبوده ولی DN ها فعال هستند (برای شبیه سازی این وضعیت می شود بعد از پیداکردن شماره پراسس resource manager از طریق jps آن را kill کرد). برای استارت دستی resource manager کافیست تا دستور زیر را اجرا کنید
yarn --daemon start resourcemanager
- در فایل yarn-site.xml مقدار hostname را به 0.0.0.0 تغییر می دهیم تا زمانی که resource manager اول از دست رفت و دومی خواست فعال شود، سرور جاری مبنا قرار داده شود؛ 
<property>
        <name>yarn.resourcemanager.hostname</name>
        <value>0.0.0.0</value>
</property>
- موارد زیر را در فایل yarn-site.xml اضافه می کنیم
<property>  
  <name>yarn.resourcemanager.bind-host</name>
  <value>0.0.0.0</value>
</property>
<property>
  <name>yarn.resourcemanager.ha.enabled</name>
  <value>true</value>
</property>
<property>
  <name>yarn.resourcemanager.cluster-id</name>
  <value>cluster1</value>
</property>
<property>
  <name>yarn.resourcemanager.ha.rm-ids</name>
  <value>rm1,rm2</value>
</property>
<property>
  <name>yarn.resourcemanager.hostname.rm1</name>
  <value>node-master</value>
</property>
<property>
  <name>yarn.resourcemanager.hostname.rm2</name>
  <value>node1</value>
</property>
<property>
  <name>yarn.resourcemanager.webapp.address.rm1</name>
  <value>node-master:8088</value>
</property>
<property>
  <name>yarn.resourcemanager.webapp.address.rm2</name>
  <value>node1:8088</value>
</property>
- اکنون باید ترتیب و اولویت resource manager ها را مشخص کنیم. ابزار مورد استفاده در این مرحله ZooKeeper است. بعد از نصب این ابزار و در ادامه مقادیر زیر را در فایل yarn-site.xml اضافه می کنیم. یکی از کاربردهای ZooKeeper این است ولی استفاده های خیلی بیشتری در بخش KafKa دارد.
روش انجام کار به اینگونه است که resource manager ها خودشان را به ZooKeeper معرفی می کنند و درصورتیکه resource manager علائم حیاتی (heart beat) به ZooKeeper ارسال نکرد، این ابزارresource manager ی که در وضعیت standby است را به عنوان active درنظر خواهد گرفت.
<property>
  <name>yarn.resourcemanager.zk-address</name>
  <value>node1:2181</value>
</property>
- حالا فایل yarn-site.xml را برروی نودها کپی کنید.
نصب ZooKeeper:
در این سناریو این ابزار را برروی node-master نصب کنید. درمحیط واقعی احتمالا Resource Manager های جایگزین برروی node-master های جایگزین راه اندازی خواهند شد. باتوجه به اینکه احتمال از دسترس خارج شدن سروری که ZooKeeper برروی آن نصب است وجود دارد، این ابزار را نیز می توان برروی سرورهای مختلف (معمولا NN های جایگزین) نصب کرد. پس از کپی کردن فایل zookeeper-3.4.13.tar.gz در /opt/ ، به مسیر opt رفته و با دستور زیر آن را باز می کرده و تغییر نام می دهیم.
tar -xzf zookeeper-3.4.13.tar.gz
mv zookeeper-3.4.13 zookeeper
- به مسیر conf از zookeeper رفته و zoo_sample.cfg را به zoo.cfg تغییر نام می دهیم.
- در داخل مسیر zookeeper برای نگهداری خود اطلاعات آن یک فولدر به نام data می سازیم.
- فایل zoo.cfg را بازکرده و مقدار dataDir را تنظیم می کنیم
dataDir=/opt/zookeeper/data/
- اکنون ZooKeeper را با فرمان زیر استارت کنید. درصورت استارت موفق با اجرای دستور jps مقدار QuorumPeerMain در نتیجه نمایش داده خواهد شد. پورت پیش فرض برای ZooKeeper مقدار 2181 است.
/opt/zookeeper/bin/zkServer.sh start
تست HA:
- اکنون stop-yarn.sh و start-yarn.sh را به ترتیب اجرا کنید تا تغییرات انجام شده در فایل های پیکربندی اثر کنند.
- هنگام استارت yarn، مشخص می کند که چه RM (resource manager ) هایی را شناسایی کرده؛ ضمن آنکه می توان پورت 8088 سرورهای RM را در مرورگر وارد و تست کرد. نکته جالب آنکه در این سناریو وقتی آدرس http://node1:8088/cluster/nodes را مشخص میکنید، مرورگر به آدرس node-master فوروارد می شود چون این نود RM اصلی است.
- با دستورات زیر نیز می توان وضعیت RM را دید. یادآوری اینکه rm1 در yarn-site.xml معرفی شده است. با اجرای این دستور مقادیر active و standby برمی گردد.
yarn rmadmin  -getServiceState rm1
- همچنین می توان پراسس rm را از روی سرور node-master ؛ kill کرد. سپس با اجرای دستور بالا مجددا وضعیت را چک کرد.
نکته: برای فعال بودن HA باید ابتدا سرویس ZooKeeper را استارت کرد و بعد از آن مابقی سرویس ها را.
SQOOP چیست؟
ابزارهای تزریق داده ها 2 دسته هستند. ابزارهای Real-Time مانند nifi، Kafka و Flume. ابزارهای آفلاین و Batch مانند SQOOP. 
با اجرای فرمان در Sqoop ابتدا یک کلاس Java ساخته شده (که کد MapReduce است) و سپس اجرا می شود. این فرمان داده ها را از بانک اطلاعات مبدا واکشی و در hadoop اعمال می نماید. Sqoop به طور پیش فرض برای هر فرمان 4 Job می سازد و به شکل موازی اجرا می کند. Sqoop برای انجام کار خود از container های yarn استفاده می نماید. در درس های بعد خواهیم دید که ابزار nifi برای انجام این کار به شکل مستقل این کار را انجام می دهند و نیازی به yarn ندارد.
- اگر جدول مورد نظر دارای کلید باشد شکستن Job می تواند با توجه به کلید انجام شود
- اگر جدول فاقد کلید باشد می توان اطلاعات آن را با فیلدی که مشابه کلید است شکست (split) و منتقل کرد
- راه دیگر هم آن است که فقط از یک Job استفاده شود و اطلاعات به شکل سریال به مقصد منتقل شوند
نصب mysql  برروی node2
- ابتدا با کاربر root به سرور متصل می شویم
- خوب است به جهت جلوگیری از تداخلات بعدی ورژنهای قدیم از mysql ی که در محیط لینوکس وجود دارد را حذف نماییم
rpm -ev  --nodeps mariadb-libs-5.5.60-1.el7_5.x86_64
- فایل زیپ mysql که دانلود کرده اید رادر محیط ویندوز باز و 4 فایل با نام های زیر را به فولدر /opt/ کپی کنید
rpm -ivh mysql-community-common-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-client-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-server-5.7.28-1.el7.x86_64.rpm
- فایل زیر را ویرایش کرده و مقدار SELINUX را برابر disabled قرار داده و در پایان لینوکس را reboot  کنید. قبل از reboot کردن باید stop-all.sh را اجراکنید تا سرویس های hadoop متوقف شوند.
vim /etc/sysconfig/selinux
- بعد از بالا آمدن node2، مجددا با کاربر  root  وارد شده و به ترتیب دستورات زیر را اجرا کنید
systemctl enable mysql
systemctl start mysqld
- mysql ی که نصب شده یک پسورد پیش فرض دارد. با دستور اول پسورد را دریافت و با فرمان دوم آن را تغییر می دهیم
grep 'temporary password' /var/log/mysqld.log
mysql_secure_installation
- کلمه عبور را بطور نمونه P@33wordMysql  تعیین کنید
- در پاسخ به پرسش remove anonymous users (کاربران پیش فرض) بگید n
- در پاسخ به پرسش disallow root login remotely بگید n
-درپاسخ به پرسش remove test database and access to it بگید n
-درپاسخ به پرسش reload privilage .....  بگید y
- اکنون برای اجرای mysql  فرمان زیر را اجرا کنید
mysql -uroot -pP@33wordMysql
- از آنجاییکه درج اطلاعات از بانک اطلاعاتی از طریق نودهای مختلف صورت می گیرد، لازم است با اجرای دستورات زیردر sql  این امکان را فراهم کنید
grant all on *.* to root@'192.168.56.10' identified by 'P@33wordMysql';
grant all on *.* to root@'192.168.56.11' identified by 'P@33wordMysql';
grant all on *.* to root@'192.168.56.12' identified by 'P@33wordMysql';
flush privileges;
نصب sqoop برروی node-master
- ابتدا فایل sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz را در مسیر /opt/ کپی کرده، به فولدر /opt/ رفته و در ادامه فولدر را تغییر نام دهید
tar -xzf sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz
mv sqoop-1.4.7.bin__hadoop-2.6.0 sqoop
- در انتهای فایل bashrc تغییرات زیر را اعمال کنید و در خاتمه source /etc/bashrc را اجرا کنید تا اثر کنه
SQOOP_HOME=/opt/sqoop
PATH=$SQOOP_HOME/bin:$PATH
export PATH
- اکنون درایور اتصال به mysql به نام mysql-connector-java-5.1.26.jar را در مسیر /opt/sqoop/lib کپی نمایید
- بعد از اجرای گام های بالا start-all.sh را اجرا کنید
استفاده از Sqoop
- ابتدا در محیط mysql اسکریپت زیر را اجرا کنید
create database sampledb;
create table address(num int, addr varchar(40));
insert into address values (1,' us ny st 10 ');
insert into address values (2,' Address 1 St. 2');
insert into address values (3,'test sddr Union St.');
insert into address values (4,' address');
insert into address values (5,' address xyz');
insert into address values (6,'Union St.');
select * from address;

create table address2(num int primary key, addr varchar(40) );
insert into address2 values (1,' us ny st 10 ');
insert into address2 values (2,' Address 1 St. 2');
insert into address2 values (3,'test sddr Union St.');
insert into address2 values (4,' address');
insert into address2 values (5,' address xyz');
insert into address2 values (6,'Union St.');
select * from address2;

create table address3(num int primary key, addr varchar(40) );
insert into address3 values (1,' us ny st 10 ');
insert into address3 values (2,' Address 1 St. 2');
insert into address3 values (3,'test sddr Union St.');
insert into address3 values (4,' address');
insert into address3 values (5,' address xyz');
insert into address3 values (6,'Union St.');
select * from address3;
- در محیط سیستم عامل با اجرای دستور زیر محتویات جدول address2 به مسیر /data/stage و با نام address2 منتقل می شود. یادآوری اینکه جدول address2 دارای کلید بوده و سیستم براساس کلید job های قابل اجرا را می شکند.
sqoop import --connect "jdbc:mysql://192.168.56.12/sampledb" \
 --username root --password P@33wordMysql --table address2 --target-dir "/data/stage/address2"
- در محیط سیستم عامل با اجرای دستور زیر محتویات جدول address به مسیر /data/stage و با نام address منتقل می شود. یادآوری اینکه جدول address فاقد کلید بوده و سیستم براساس  فیلدی که ماهیتی مشابه کلید دارد(اینجا num)  شکست را انجام می دهد.
sqoop import --connect "jdbc:mysql://192.168.56.12/sampledb" \
 --username root --password P@33wordMysql --table address2 --target-dir "/data/stage/address" --split-by num
- در محیط سیستم عامل با اجرای دستور زیر محتویات جدول address به مسیر /data/stage و با نام address منتقل می شود. یادآوری اینکه جدول address فاقد کلید بوده و سیستم براساس  فیلدی که ماهیتی مشابه کلید دارد(اینجا num)  شکست را انجام می دهد. پارامتر آخر باعث می شود تا اجرا در یک job پشت سرهم انجام شود.
sqoop import --connect "jdbc:mysql://192.168.56.12/sampledb" \
 --username root --password P@33wordMysql --table address2 --target-dir "/data/stage/address" -m 1