大数据容器化-基于Kubernetes(k8s)构建spark运行环境
Apache Spark
在大數(shù)據(jù)處理與分析領(lǐng)域,Apache Spark無疑占據(jù)著重要地位。它的特點(diǎn)是基于內(nèi)存計(jì)算,支持各類資源管理平臺(tái),其中以YARN最為常見,同時(shí)又與Hadoop平臺(tái)集成,在集群節(jié)點(diǎn)以HDFS作為分布式文件存儲(chǔ)系統(tǒng)。
我們可以先看一下搭建一個(gè)常見的Apache Spark大數(shù)據(jù)平臺(tái)需要哪些步驟:
安裝Hadoop集群
- 配置HDFS
- 配置YARN
- 安裝Spark
- 配置Spark與YARN集成
事實(shí)上如果參閱官方文檔,還有更多細(xì)節(jié)檢查與配置,有過大數(shù)據(jù)相關(guān)領(lǐng)域從業(yè)經(jīng)驗(yàn)的人都知道,要搭建一套可用的大數(shù)據(jù)環(huán)境并不容易,再加上后期維護(hù),就更吃力了,而一套穩(wěn)定的大數(shù)據(jù)平臺(tái)正是進(jìn)行大數(shù)據(jù)應(yīng)用開發(fā)的基礎(chǔ)。根據(jù)筆者了解,有不少公司正是因?yàn)榇髷?shù)據(jù)平臺(tái)搭建及配置的復(fù)雜性等原因,不得不在多個(gè)測試環(huán)境中,共用一套大數(shù)據(jù)平臺(tái),這種方式長期看維護(hù)成本較高,也可能存在安全隱患。
大數(shù)據(jù)領(lǐng)域需要一些變化,而Kubernetes的出現(xiàn)則提供了契機(jī)。
Kubernete(以下簡稱k8s)是容器集群管理系統(tǒng),是一個(gè)開源的平臺(tái),可以實(shí)現(xiàn)容器集群的自動(dòng)化部署、自動(dòng)擴(kuò)縮容、維護(hù)等功能。通過Kubernetes你可以:
- 快速部署應(yīng)用
- 快速擴(kuò)展應(yīng)用
- 無縫對(duì)接新的應(yīng)用功能
- 節(jié)省資源,優(yōu)化硬件資源的使用
大數(shù)據(jù)社區(qū)
隨著K8s社區(qū)的發(fā)展壯大,微服務(wù)及容器化被越來越多的公司應(yīng)用到生產(chǎn)環(huán)境。與此同時(shí),K8s也成為容器編排的首選平臺(tái)。大數(shù)據(jù)社區(qū)在容器化進(jìn)程中當(dāng)然也是不甘落后的。
Spark自2.3開始官方支持K8sFlink自1.9開始官方支持K8sHue官方Helm chart包Hive以MR3為執(zhí)行引擎支持K8sAirflow自1.10開始支持K8sPresto支持K8s……
可以看到整個(gè)大數(shù)據(jù)社區(qū)也在積極支持容器化,但大數(shù)據(jù)的容器化并不是生硬地將各個(gè)組件搬到K8s上,以Spark on YARN為例,核心組件YARN作為資源調(diào)度器,其結(jié)構(gòu)如下圖所示
下圖講述了Apache Spark on YARN的工作方式:
YARN ResourceManager的功能為:
負(fù)責(zé)集群中所有資源的統(tǒng)一管理和分配,它接收來自各個(gè)節(jié)點(diǎn)(NodeManager)的資源匯報(bào)信息,并把這些信息按照一定的策略分配給各個(gè)應(yīng)用程序
了解K8s的同學(xué)可以看出YARN的功能其實(shí)與K8s Scheduler的功能非常類似
Kubernetes 調(diào)度器是一個(gè)策略豐富、拓?fù)涓兄⒐ぷ髫?fù)載特定的功能,調(diào)度器顯著影響可用性、性能和容量。調(diào)度器需要考慮個(gè)人和集體的資源要求、服務(wù)質(zhì)量要求、硬件/軟件/政策約束、親和力和反親和力規(guī)范、數(shù)據(jù)局部性、負(fù)載間干擾、完成期限等。
所以與其將YARN生搬到K8s中(早期確實(shí)是這樣做的),何不用K8s調(diào)度器替換掉YARN,使得Spark適應(yīng)K8s呢? 事實(shí)上社區(qū)確實(shí)是在這個(gè)方向努力嘗試,并且自Spark 2.3開始,實(shí)驗(yàn)性支持使用K8s原生Scheduler替代YARN。
spark on k8s:
在該方案中
客戶端通過spark-submit將任務(wù)提交到K8s集群中,并在集群中啟動(dòng)一個(gè)Spark Driver Pod;
Spark Driver啟動(dòng)相應(yīng)的Executor Pod, 組成一個(gè)Spark Application集群并執(zhí)行作業(yè)任務(wù);
任務(wù)執(zhí)行完成后,Executor Pod會(huì)被銷毀, 而Driver Pod會(huì)持久化相關(guān)日志,并保持在’completed’狀態(tài),直到用戶手清理或被K8s集群的垃圾回收機(jī)制回收.
Spark原生支持K8s的好處也是很明顯的:可以更好的利用K8s的集群資源,通過K8s賦能,更好的進(jìn)行資源的隔離。這個(gè)方案不太友好的地方在于:spark-submit在K8s集群之外,使用非聲明式的提交接口,實(shí)際使用起來不夠友好。
將Spark應(yīng)用遷移到K8s環(huán)境中
Spark Operator是Google基于Operator模式開發(fā)的一款的工具, 用于通過聲明式的方式向K8s集群提交Spark作業(yè),并且負(fù)責(zé)管理Spark任務(wù)在K8s中的整個(gè)生命周期,其工作模式如下圖所示:
我們可通過Hem安裝spark-operator
$ helm repo add incubator http://storage.googleapis.com/kubernetes-charts-incubator $ helm install incubator/sparkoperator --namespace spark-operator創(chuàng)建服務(wù)用戶及綁定權(quán)限
$ kubectl create serviceaccount spark $ kubectl create clusterrolebinding spark-role --clusterrole=edit --serviceaccount=default:spark --namespace=default一個(gè)典型的Spark應(yīng)用在K8s中的資源描述文件spark-pi.yaml如下所示
apiVersion: "sparkoperator.k8s.io/v1beta2" kind: SparkApplication metadata:name: spark-pinamespace: default spec:type: Scalamode: clusterimage: "gcr.io/spark-operator/spark:v2.4.4"imagePullPolicy: AlwaysmainClass: org.apache.spark.examples.SparkPimainApplicationFile: "local:///opt/spark/examples/jars/spark-examples_2.11-2.4.4.jar"sparkVersion: "2.4.4"restartPolicy:type: Nevervolumes:- name: "test-volume"hostPath:path: "/tmp"type: Directorydriver:cores: 1coreLimit: "1200m"memory: "512m"labels:version: 2.4.4serviceAccount: sparkvolumeMounts:- name: "test-volume"mountPath: "/tmp"executor:cores: 1instances: 1memory: "512m"labels:version: 2.4.4volumeMounts:- name: "test-volume"mountPath: "/tmp"部署運(yùn)行
$ kubectl apply -f spark-pi.yaml計(jì)算與存儲(chǔ)分離
計(jì)算與存儲(chǔ)耦合存在的問題:
當(dāng)存儲(chǔ)或計(jì)算其中一方資源不足時(shí),只能同時(shí)對(duì)兩者進(jìn)行擴(kuò)容,導(dǎo)致擴(kuò)容的經(jīng)濟(jì)效率比較低(另一種擴(kuò)容的資源被浪費(fèi)了);
在云計(jì)算場景下,不能實(shí)現(xiàn)真正的彈性計(jì)算,因?yàn)橛?jì)算集群中也有數(shù)據(jù),關(guān)閉閑置的計(jì)算集群會(huì)丟失數(shù)據(jù)。
因?yàn)轳詈蠈?dǎo)致的以上這些問題,導(dǎo)致很多公司不得不考慮這種耦合的必要性。而Hadoop的架構(gòu)設(shè)計(jì)正是計(jì)算與存儲(chǔ)耦合,這種設(shè)計(jì)并不適合云原生架構(gòu)。而作為大數(shù)據(jù)存儲(chǔ)的基石-HDFS,目前并無官方的K8s解決方案,不過在K8s社區(qū)本身就有許多優(yōu)秀的存儲(chǔ)解決方案-MINIO
MinIO 是一個(gè)基于Apache License v2.0開源協(xié)議的對(duì)象存儲(chǔ)服務(wù)。它兼容亞馬遜S3云存儲(chǔ)服務(wù)接口,非常適合于存儲(chǔ)大容量非結(jié)構(gòu)化的數(shù)據(jù),例如圖片、視頻、日志文件、備份數(shù)據(jù)和容器/虛擬機(jī)鏡像等,而一個(gè)對(duì)象文件可以是任意大小,從幾kb到最大5T不等。而且實(shí)驗(yàn)數(shù)據(jù)表明,其性能絲毫不遜色于HDFS
安裝MINIO也非常容易
$ helm install stable/minio我們以WordCount,數(shù)據(jù)讀寫使用minio存儲(chǔ)系統(tǒng)(兼容亞馬遜S3云存儲(chǔ)服務(wù)接口)
JavaRDD<String> textFile = sc.textFile("s3a://..."); JavaPairRDD<String, Integer> counts = textFile.flatMap(s -> Arrays.asList(s.split(" ")).iterator()).mapToPair(word -> new Tuple2<>(word, 1)).reduceByKey((a, b) -> a + b); counts.saveAsTextFile("s3a://...");由于兼容亞馬遜S3云存儲(chǔ)服務(wù)接口這一優(yōu)勢,minio也同樣可以作為Hive數(shù)據(jù)倉庫的可選存儲(chǔ)系統(tǒng)。
<property> <name>fs.s3a.path.style.access</name> <value>true</value> <description>Enable S3 path style access.</description> </property> <property> <name>hive.metastore.warehouse.dir</name> <value>s3a://hive/warehouse</value> </property>總結(jié)
通過以上論述,在K8s集群上搭建Spark大數(shù)據(jù)平臺(tái),相比傳統(tǒng)YARN調(diào)度方式而言更為簡潔,MINIO可作為大數(shù)據(jù)的存儲(chǔ)系統(tǒng),在保證數(shù)據(jù)的持久性的同時(shí),也實(shí)現(xiàn)了大數(shù)據(jù)計(jì)算系統(tǒng)與存儲(chǔ)系統(tǒng)的解耦。
參考
https://www.linode.com/docs/databases/hadoop/install-configure-run-spark-on-top-of-hadoop-yarn-cluster/
https://github.com/GoogleCloudPlatform/spark-on-k8s-operator
https://spark.apache.org/docs/latest/running-on-kubernetes.html
https://blog.min.io/hdfsbenchmark/
https://databricks.com/session/taking-advantage-of-a-disaggregated-storage-and-compute-architecture
https://blog.minio.io/modern-data-lake-with-minio-part-2-f24fb5f82424
原文鏈接:https://zhuanlan.zhihu.com/p/134611416
總結(jié)
以上是生活随笔為你收集整理的大数据容器化-基于Kubernetes(k8s)构建spark运行环境的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nginx https配置
- 下一篇: flyway命令行使用示例:指定conf