如何通過AWS EMR降低集群計算成本,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
AWS EMR是一個計算集群??梢酝ㄟ^ta創建自定義配置的虛擬機,并自動安裝所需計算框架(Spark,Hadoop,Hive等),以便用來進行大數據計算。
公司目前有一個項目,通過爬蟲收集數據,離線計算得到用戶畫像,并將最終結果寫入rds,通過api向外展示數據。
計算框架 Spark
調度框架 Airflow
數據存儲 Hadoop,Mysql
數倉工具 Hive,Presto
輔助工具 Zepplin
腳本語言 Java,Scala,Python
環境
我們在某云廠商開了6臺虛擬器(4核8G),spark on yarn模式運行,其中1臺作為主節點,運行hadoop主節點和airflow調度程序,其余作為數據節點。
計算過程
通過Spark Streaming將數據落地到Hadoop
Airflow定時向主節點通過Spark-submit方式提交命令
Spark計算后將最終結果寫入Mysql
平時開發人員可以在Zepplin進行查詢
效果
計算流程可以正常進行
思考
通過一段時間的觀察分析,我們發現
大部分計算任務都能在較短時間內完成
機器每天閑置時間很長
業務沒有很高的實時性要求
高配置虛擬器成本很高
結論
基于現狀,我們希望能有個即開即用的系統,就像電腦一樣,要用就打開,用完就關閉。經過調研,最終選擇了AWS的EMR。
環境
在將系統遷移到AWS EMR之后,在AWS上開了一臺虛擬器(1核2G)運行Airflow和Kinesis
這臺虛擬器需要一直運行,但Airflow本身不需要高配置
計算過程
通過Kinesis將數據落到S3
Airflow定時發起任務
發起創建EMR請求
可自定義機器配置,要安裝的計算框架,也可覆蓋框架配置??赏ㄟ^Python腳本檢測集群是否創建成功
提交計算任務
關閉集群
效果
計算流程可以正常進行,但不需要長開機器了,只需要一臺低配來觸發定時任務即可
思考
通過一段時間的觀察
EMR費用比起虛擬器,確實便宜很多
可以通過console臺查看集群狀態,控制集群開關
不方便的地方,平時要查看Hadoop的數據,需要自己寫腳本拉取,不能使用輔助工具了
準備工作
注冊AWS賬號,登錄
開通EMR,S3
開通S3的目的是為了持久化數據,因為EMR集群本身不帶額外硬盤,需要外部介質儲存
開通AWS內網可訪問的Mysql
如果不用Hive,可跳過這一步,同理,需要外部介質儲存Hive的數據結構
準備創建EMR集群的腳本
這里有個坑,開始我們使用的AWS SDK來做這件事,但無法自定義計算框架配置(應該是BUG),最初我們通過修改SDK源碼解決了這個問題,但后來發現基本沒用到SDK其他功能時,我們將這部分代碼提成了單獨的文件,由于使用了Airflow進行調度,所以決定用了Python
編寫Spark任務,打包上傳至S3
EMR LIB
# coding: UTF-8 import boto3, json, requests, requests from datetime import datetime def get_region(): # 這個地址不用改 r = requests.get("http://169.254.169.254/latest/dynamic/instance-identity/document") response_json = r.json() return response_json.get('region') def client(region_name): global emr emr = boto3.client('emr', region_name=region_name) # 創建EMR def create_cluster(name): param = { # 修改需要的框架 "Applications":[{ "Name":"Hadoop" },{ "Name":"Hive" },{ "Name":"Spark" }], # 這里的名字會顯示到控制臺 "Name":name, "ServiceRole":"EMR_DefaultRole", "Tags":[], "ReleaseLabel":"emr-5.26.0", "Instances":{ "TerminationProtected":False, "EmrManagedMasterSecurityGroup":"sg-0085fba9c3a6818f5", "InstanceGroups":[{ "InstanceCount":1, "Name":"主實例組 - 1", "InstanceRole":"MASTER", "EbsConfiguration":{ "EbsBlockDeviceConfigs":[{ "VolumeSpecification":{ "SizeInGB":32, "VolumeType":"gp2" }, "VolumesPerInstance":1 }] }, # 修改需要的硬件配置 "InstanceType":"m4.large", "Market":"ON_DEMAND", "Configurations":[{ # 修改Hive的meta源 "Classification":"hive-site", "Properties":{ "javax.jdo.option.ConnectionURL":"jdbc:mysql://host:port/db?useUnicode=true&characterEncoding=UTF-8", "javax.jdo.option.ConnectionDriverName":"org.mariadb.jdbc.Driver", "javax.jdo.option.ConnectionUserName":"user", "javax.jdo.option.ConnectionPassword":"pwd" } },{ "Classification":"yarn-env", "Properties":{}, "Configurations":[{ "Classification":"export", "Properties":{ "AWS_REGION":"cn-northwest-1", "S3_ENDPOINT":"s3.cn-northwest-1.amazonaws.com.cn", "S3_USE_HTTPS":"0", "S3_VERIFY_SSL":"0" } }] }] },{ "InstanceRole":"CORE", "InstanceCount":1, "Name":"核心實例組 - 2", "Market":"ON_DEMAND", # 修改需要的硬件配置 "InstanceType":"r5d.2xlarge", "Configurations":[{ "Classification":"hive-site", "Properties":{ "javax.jdo.option.ConnectionURL":"jdbc:mysql://host:port/db?useUnicode=true&characterEncoding=UTF-8", "javax.jdo.option.ConnectionDriverName":"org.mariadb.jdbc.Driver", "javax.jdo.option.ConnectionUserName":"user", "javax.jdo.option.ConnectionPassword":"pwd" } },{ "Classification":"yarn-env", "Properties":{}, "Configurations":[{ "Classification":"export", "Properties":{ "AWS_REGION":"cn-northwest-1", "S3_ENDPOINT":"s3.cn-northwest-1.amazonaws.com.cn", "S3_USE_HTTPS":"0", "S3_VERIFY_SSL":"0" } }] }] },{ # 修改需要的工作節點數 "InstanceCount":4, "Name":"任務實例組 - 4", "InstanceRole":"TASK", "EbsConfiguration":{ "EbsBlockDeviceConfigs":[{ "VolumeSpecification":{ "SizeInGB":32, "VolumeType":"gp2" }, "VolumesPerInstance":4 }] }, # 修改需要的硬件配置 "InstanceType":"r5d.2xlarge", "Market":"ON_DEMAND", "Configurations":[{ "Classification":"hive-site", "Properties":{ "javax.jdo.option.ConnectionURL":"jdbc:mysql://host:port/db?useUnicode=true&characterEncoding=UTF-8", "javax.jdo.option.ConnectionDriverName":"org.mariadb.jdbc.Driver", "javax.jdo.option.ConnectionUserName":"user", "javax.jdo.option.ConnectionPassword":"pwd" } },{ "Classification":"yarn-env", "Properties":{}, "Configurations":[{ "Classification":"export", "Properties":{ "AWS_REGION":"cn-northwest-1", "S3_ENDPOINT":"s3.cn-northwest-1.amazonaws.com.cn", "S3_USE_HTTPS":"0", "S3_VERIFY_SSL":"0" } }] }] }], "KeepJobFlowAliveWhenNoSteps":True, "Ec2SubnetId":"subnet-027bff297ea95039b", "Ec2KeyName":"hifive.airflow", "EmrManagedSlaveSecurityGroup":"sg-05a0e076ee7babb9e" }, "JobFlowRole":"EMR_EC2_DefaultRole", "Steps":[{ "HadoopJarStep":{ "Args":["state-pusher-script"], "Jar":"command-runner.jar" }, "Name":"Setup Hadoop Debugging" }], "ScaleDownBehavior":"TERMINATE_AT_TASK_COMPLETION", "VisibleToAllUsers":True, "EbsRootVolumeSize":10, "LogUri":"s3n://aws-logs-550775287661-cn-northwest-1/elasticmapreduce/", "AutoScalingRole":"EMR_AutoScaling_DefaultRole" } cluster_response = emr.run_job_flow(**param) return cluster_response['JobFlowId'] # 獲取EMR訪問入口 def get_cluster_dns(cluster_id): response = emr.describe_cluster(ClusterId=cluster_id) return response['Cluster']['MasterPublicDnsName'] # 等待集群創建完成 def wait_for_cluster_creation(cluster_id): emr.get_waiter('cluster_running').wait(ClusterId=cluster_id) # 關閉EMR def terminate_cluster(cluster_id): emr.terminate_job_flows(JobFlowIds=[cluster_id])
調用測試
# 創建6臺機器的集群(1 master,1 core,4 worker) cluster_id = create_cluster("biz_daily_2020_10_09") # 阻塞直到創建成功 wait_for_cluster_creation(cluster_id) # dns相當于虛擬機的ssh地址,每次都不同 # ssh登錄這個地址可以提交spark命令了,這里使用Airflow的SSHOperator模擬登錄并提交命令 cluster_dns = get_cluster_dns(cluster_id) # 關閉集群 terminate_cluster(cluster_id)
Airflow 1.9.0的時間模板{{ ds }}生成的是格林尼治時間,要改為我國時間,需手動加8小時,不知道新版本是否支持本地時間。
ssh登錄dns用戶名hadoop,這個用戶是AWS生成的,似乎無法修改。
看完上述內容,你們掌握如何通過AWS EMR降低集群計算成本的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。