Viết ứng dụng Word Count trên Spark bằng Scala, sử dụng Intellij IDEA Community

Sharing is caring!

Ở bài mở đầu, tui đã hướng dẫn cài đặt Spark 1.6.3 trên Windows 10 rồi. Trong bài này, tui thử viết một ứng dụng chạy trong môi trường Spark bằng ngôn ngữ Scala với IDE Intellij IDEA phiên bản Community.

Đối với Spark, các bạn có thể viết ứng dụng bằng 4 ngôn ngữ: Scala, Java, Python, R. Nhưng tui lại thích chọn Scala bởi vì:

  • Spark được build bằng Scala
  • Đã từng làm qua Java, C#, nhưng lại thích kiểu lập trình không cần khai báo datatype như PHP mà Spark không hổ trợ PHP cho nên quyết định dùng Scala bởi Scala có cú pháp gần giống Java mà lại không cần khai báo datatype giống PHP

Đó là ý kiến cá nhân của tui thôi, còn các bạn thích ngôn ngữ nào trong 3 cái còn lại thì cứ dùng nó, chả ảnh hưởng ai cả đâu.

1. Cài đặt IDE Intellij IDEA:

Cái này dễ lắm, các bạn download Intellij IDEA phiên bản community 2016.3.1 cho Windows ở đây: https://www.jetbrains.com/idea/download/#section=windows, các bạn chọn download bên mục Community. Intellij IDEA cần JDK nên nếu ai đọc bài mở đầu vài cài JDK rồi thì thôi, ai chưa cài JDK thì xem ở bài mở đầu nha

Sau khi cài đặt xong, các bạn chạy Intellij IDEA lên, nếu nó có hỏi bạn là muốn cài scala plugin không thì các bạn cứ làm theo hướng dẫn của nó mà cái scala plugin. Nếu không thì các bạn install bằng tay cũng chả sao.

Intellij IDEA mở lên nó ra màn hình welcome như thế này:

Click Configure, chọn Plugins, gõ chữ scala vào ô search

Do máy tui đã cài Scala plugin rồi nên nó hiển thị vậy, nếu là lần đầu cài đặt thì chổ cái nút Uninstall sẽ là nút Install, các bạn cứ click Install là được. Xong nha, qua phần tạo project scala

2. Tạo project Scala bằng Maven:

Ngay màn hình welcome, các bạn click Create New Project

Chọn Maven, Click Create from archetype, chọn org.apache.camel.archetypes:camel-archetype-scala, click Next

Các mục trên, các bạn có thể đặt tên không cần giống tui đâu nha. Chú ý là mục GroupId, các từ phải được phân cách bằng dấu chấm nha. Click Next

Giữ nguyên, click Next

Mục Project Name thì các bạn có thể thay đồi nha, tui thì giữ nguyên. Mục Project Location: chọn thư mục để lưu project. Click Finish

Đợi vài giây cho IDE nó load cái project lên thì các bạn thấy bên góc dưới bên phải nó có popup một cái form:

Các bạn chọn Import Changes, đừng chọn Enable Auto Import để mỗi khi các bạn thay đổi các dependency trong file pom.xml thì các bạn có thể kiểm soát được là nên import hay không, lỡ có gõ sai thì không phải chờ nó Auto Import rồi lại đi chỉnh sửa lại.

Mặc định khi tạo project bằng Maven thì cái file pom.xml nó sẽ tự động mở lên nha các bạn

Ở cửa sổ Porject, các bạn mở cây thư mục như hình:

Nó tạo sẳn cho mình cái package com.vincentle.spark.training chính là cái GroupId hồi nảy khi tạo project, nó cũng tạo sẳn 2 cái file scala một cái là MyRouteBuilder class, một cái là MyRouteMain object. Các bạn chọn 2 cái file này, click chuột phải chọn Delete để xóa nó đi. Xong, các bạn tạo một object mới tên là WordCount bằng cách click chuột phải vào package com.vincentle.spark.training, chọn New, chọn Scala class

Nó sẽ hiển lên cái của sổ sau:

Mục Name: gõ WordCount. Mục Kind thì chọn là Object. Click OK

Khi đó file WordCount.scala sẽ được tạo bên dưới package com.vincentle.spark.training. Double click vào file này để mở nó lên. Nội dung file mặc định của nó là:

Để run một file scala, các bạn phải tạo hàm main cho nó và thử in câu “Hello World” kinh điển ra màn hình console để xem scala nó có build và run được hay không nha.

Hàm main là nơi chương trình bắt đầu thực thi. Trong hàm main tui dùng hàm println() để in câu “Hello World”. Ai từng làm qua Java sẽ thấy hàm println này rất quen thuộc nà.

Các bạn có thể viết hàm main không có :Unit= nó vẫn chạy nha các bạn.

Để run một file scala, các bạn chuột phải vào cái tên file bên của sổ project rồi click Run ‘WordCount’ hoặc là chuột phải vào bên của sổ soạn thảo file đó và chọn Run ‘WoudCount’ hoặc nhấn tổ hợp phím Ctrl + Shift + F10

Sau khi click Run mà ra được như hình có nghĩa scala chạy ổn:

 

3. Viết code cho WordCount:

Đầu tiên, để có thể viết ứng dụng trên Spark, các bạn phải xem qua một chút về các dependency (là các file thư viện liên quan đến Spark cũng như Scala). Để tiện cho việc quản lý các dependency thì Maven hổ trợ rất tốt về khoản này, mọi thứ đều nằm trong cái file pom.xml, việc còn lại thì Maven lo, các bạn khỏi lo.

Mở file pom.xml lên nha các bạn, tìm các tag <properties></properties> thêm vào các tag sau:

scala.version: Do tui cài Spark 1.6.3, nó build bằng Scala 2.10 cho nên mình phải bảo Maven là dùng Scala 2.10

spark.scala.built.version: cái này là cái version của spark core khi nó build bằng scala 2.10

spark.version: cái này là version của Spark

jackson.version: cái này được dùng để chuyển đổi object sang json. Do mặc định khi tạo project, các version của nó không thóng nhất với nhau, cho nên tui bỏ vào depedency luôn, nếu không khi build file scala nó báo lỗi.

Tiếp, tới cái tag <dependencies></dependencies>, các bạn thêm vô như sau:

Khi các bạn thay đổi gì đó trong file pom.xml, thì Intellij IDEA nó sẽ popup cái form báo là “Maven project need to be imported”, sau khi thay đổi xong xuôi, các bạn click Import Changes nha để Maven nó cập nhật các file thư viện lại.

Click Import Changes để Maven nó cập nhật lại thư viện.

Trước khi cập nhật:

Sau khi cập nhật nó load về quá trời thư viện luôn

Xong phần dependency, giờ viết code WordCount nha, rồi tui sẽ giải thích code:

Giải thích code:

Đầu tiên là các bạn tạo một biến config để báo cho Spark biết là cái ứng dụng của bạn tên là gì bằng hàm setAppName(), bạn muốn chạy Spark ở máy nào bằng hàm setMaster()

Khi bạn gõ chữ SparkConfSparkContext thì Intellij IDEA nó sẽ auto suggest cho bạn, khi bạn chọn và nhấn Enter thì nó tự động import thư viện

Đó là Scala nó viết tắt nếu các class có cùng package, nếu bạn không quen, bạn có thê viết rời ra như Java cũng được

Để làm việc trên Spark thì các bạn phải cần một SparkContext với cái config đã tạo ở trên, đại khái như một phiên làm việc riêng, không ai đụng ai.

Tiếp theo, tui có một file tên là input.txt muốn đếm số từ trong đó (tiếng Anh cho dễ):  Happy-Grin

Load nội dung file input.txt vào biến contents thông qua biến sparkCtx với hàm textFile()

trong file input.txt tui có 5 dòng, thì hàm flatMap này nó đi duyệt qua từng dòng, ở mỗi dòng nó sẽ tách từ bằng khoảng trắng. tới đây tui có một list các từ chứa trong biến words.

Chưa cần quan tâm đến các từ giống nhau nha, coi như mỗi từ có giá trị là 1. Hàm map() sẽ tạo một collection mà mỗi item của nó là một tuple2 có key là chính cái từ đó và giá trị là 1.

Giải thích cái Tuple2 một chút, trong Scala, cái kiểu Tuple này ngộ lắm, muốn Tuple bao nhiêu là có bấy nhiêu (từ 2->22).

Tuple3(1, “xxxx”, “yyyy”)

Tuple4(“xxx”, “yyyy”, 2, “zzzz”)

Tuple22 thì có 22 phần tử. Vậy đó, nó giống như array 1 chiều vậy, bạn có thể viết mà không cần chữ Tuple luôn, nó vẫn hiểu

Viết như trên nó vẫn chạy bình thường nha các bạn, nó vẫn hiểu là Tuple2.

Hàm reduceByKey() nó sẽ sum theo key, như lúc nảy, mỗi một word tui cho nó giá trị là 1, vậy nếu tui có 3 từ giống nhau, tui được giá trị là 3. Các bạn thấy cái tham số (i, j) => i + j truyền vô cho hàm reduceByKey nó lạ lạ không, tui còn thấy lạ nữa là.  Overjoy . Sau một lúc tìm kiếm và hiểu, tui giải thích cho các bạn nha:

Giả sử tui có 3 cái Tuple2: item1: (“Spark”, 1), item2: (“Spark”, 1), item3: (“Spark”, 1)

Rồi, cái tham số (i, j) => i + j có nghĩa là khi hàm reduceByKey nó duyệt qua từng item:

item1, key là “Spark”, xong nó khởi tạo giá trị cho biến i là 0, cái biến j chính là value của item1 chính là 1.

i + j lúc này là 0 + 1 = 1, gán i = 1

item2, key là “Spark”, lúc này i = 1(ở bước item 1),

thì i + j sẽ là 1 + 1 = 2, gán i = 2

item3: key vẫn là “Spark”, lúc này i = 2

thì i + j sẽ là 2 + 1 = 3, gán i = 3

cuối cùng cái key là “Spark” và có value là 3

Các bạn có thể tìm hiểu thêm về hàm reduceByKey ở đây: http://backtobazics.com/big-data/spark/apache-spark-reducebykey-example/

Sau này, khi đọc tài liệu, các bạn có thể thấy người khác viết như thế này, gọn hơn, nhưng khó hiểu hơn:

thay thế cái cụm (i, j) => i + j bằng _+_

Tiếp theo, tui dùng hàm sortByKey() để sắp sếp collection lại theo key (theo ký tự đầu tiên của mỗi từ), dùng hàm foreach() với tham số là hàm println để in collection ra màn hình console.

Cuối cùng là kết thúc cái context để báo cho Spark biết là ta đã xong.

Kết quả sau khi run file WordCount.scala

Kết quả có phân biệt chữ hoa chữ thường nha các bạn, do trong bảng mã ASCII, ký tự chữ hoa có giá trị nhỏ hơn chữ thường nha các bạn.

Để dễ hình dung hơn các bước xử lý, các bạn xem cái hình sau:

Vậy là chạy ra kết quả rồi nha, ổn nha. Dừng lại được chưa ta?  Disapproval Chưa đâuuuuuuuu! tới đây, các bạn chỉ mới chạy trong môi trường của IDE thôi, phải deploy thực tế lên Spark kìa, tiếp nha.

4. Build và deploy file jar lên Spark:

Giờ các bạn đã có source file WordCount.scala, giờ phải build nó ra file jar, làm như sau:

chọn menu File -> Project Structure… hoặc click cái icon bên gó phải trên của IDE như hình:

Nó sẽ show cái cửa sổ Project Structure

Chọn Artifacts, sau đó click cái dấu + màu xanh lục

chọn JAR, sau đó chọn From modules with dependencies..

Mục Main Class thì click cái nút ba chấm, chọn cái file WordCount, xong click OK

Các bạn đánh dấu chọn hết các dòng như hình, chỉ chừa lại cái dòng ‘wordcount’ compile output (cái chữ ‘wordcount’ sẽ thay đổi tùy thuộc vào tên project bạn đặt nha), sau đó chuột phải vài cái list đã chọn, click Remove. Lý do là các bạn không cần phải build kèm mấy file thư viện này, ở những bài sau, khi nào cần thư viện nào build kèm, tui sẽ nói rõ hơn, còn hiện giờ mình chỉ cần cái thư viện Spark thôi, mà trên Spark nó có sẳn rồi, không cần kèm theo.

Các bạn chú ý cái mục Output Directory nha, khi build xong thì file jar nó sẽ được tạo ở đó, với máy tui thì nó là E:\projects\intellij\workspace\wordcount\out\artifacts\wordcount_jar. Xong, click OK

Trở lại màn hình chính, các bạn chọn menu Build -> Build Artifacts…

Nó hiện ra cái popup nhỏ, chọn wordcount.jar -> Build

Sau khi build xong, ngó qua cái cửa sổ project, nó sẽ load cái thư mục như trong cái mục Output Directory khi nảy, các bạn sẽ thấy file wordcount.jar trong đó

Có file jar rồi, mở Command Prompt lên để submit file jar này lên Spark nha các bạn.

Mở Command Prompt lên, các bạn gõ lệnh như sau:

các bạn có thể tham khảo thêm các option của lệnh spark-submit tại đây: http://spark.apache.org/docs/latest/submitting-applications.html

Sau khi run lệnh này, các bạn chờ tí sẽ thấy kết quả như sau:

Oh, may quá, kết quả ra y như lúc chạy trên Intellij IDEA. Xong rồi đó, vậy là kết thúc bày này nha, mệt quớ.  Tired

 

Sharing is caring!

Cài đặt Apache Spark 1.6.3 trên Windows 10
Truy vấn dữ liệu từ MongoDB với Apache Spark

Vincent Le

Tui là Lê Minh Đạt, tên tiếng anh là Vincent(do thích nhân vật Vincent Valentine, ai từng là fan của trò Final Fantasy VII thì sẽ biết nhân vật này, hehe). Đang tập tành làm một blogger viết về mảng lập trình, mong muốn được chia sẻ những gì đã học được, tích góp được trong 10 năm đi làm thợ code.

shares