
Prerequisites
Để sử dụng được Apache Spark cần cài đặt:
- Cài đặt Java JDK.
- R + R Studio.
- Thư viện sparklyr.
Sau khi cài đặt xong kiểm tra một số thông tin về phiên bản:
library(sparklyr)
spark_installed_versions()
## spark hadoop dir
## 1 2.4.3 2.7 C:\\Users\\Admin\\AppData\\Local/spark/spark-2.4.3-bin-hadoop2.7
Như vậy Spark (Version 2.4.3) và Hadoop (Version 2.7) cũng được install trên local machine.
Connecting
Giả sử rằng việc cài đặt và thiết lập môi trường để sử dụng Apache Spark (gọi tắt là Spark) đã được hoàn thành. Các chương sau sẽ giải thích việc tìm, cài đặt và kết nối nhiều Spark Cluster trên nhiều máy tính khác nhau. Với mục đính minh họa, chương này tập trung vào vận hành code trên local cluster (máy tính cá nhân).
Để kết nối với local cluster trên máy tính cá nhân thực hiện R codes dưới đây:
sc <- spark_connect(master = "local", version = "2.4.3")
Chúng ta có thể xem thêm một số thông tin khác về local cluster bằng lệnh sau:
Sử dụng Apache Spark
Sau khi kết nối với local cluster chúng ta sử dụng bộ dữ liệu mtcars (có săn trong R Environment) để minh họa. Trước hết xem qua bộ dữ liệu này:
## mpg cyl disp hp drat wt qsec vs am gear carb
## Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
## Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
## Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
## Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
## Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
## Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
Lưu lại bộ dữ liệu này ở định dạng .csv để sử dụng sau này nếu cần thiết:
write.csv(mtcars, "cars.csv", row.names = FALSE)
Sử dụng lệnh copy_to()
để copy bộ dữ liệu mtcars từ môi trường R vào Apache Spark:
cars <- copy_to(sc, mtcars)
Chúng ta có thể access bộ dữ liệu này thông qua R. Ví dụ:
## # Source: spark<?> [?? x 11]
## mpg cyl disp hp drat wt qsec vs am gear carb
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4
## 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4
## 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1
## 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1
## 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2
## 6 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1
Web Interface
Hầu hết Spark commands được thực hiện từ Rstudio/R console. Tuy nhiên việc theo dõi (và các quá trình khác) được thực hiện thông qua giao diện Web của Spark. Giao diện này là môt web application được cung cấp bởi Spark bằng cách thực hiện lệnh sau:
Kết quả sẽ như dưới đây:
# Data Query and Manipulation
Khi sử dụng Spark thông qua R chúng ta có thể sử dụng các ngôn ngữ truy vấn dữ liệu. Chẳng hạn sử dụng SQL để đếm số dòng:
library(DBI)
dbGetQuery(sc, "SELECT count(*) FROM mtcars")
## count(1)
## 1 32
Hoặc sử dụng các hàm của thư viện dplyr:
library(dplyr)
cars %>%
group_by(cyl) %>%
count(sort = TRUE)
## # Source: spark<?> [?? x 2]
## # Ordered by: desc(n)
## cyl n
## <dbl> <dbl>
## 1 8 14
## 2 4 11
## 3 6 7
Modelling
Sau khi load bộ dữ liệu mtcars vào Spark Environment chúng ta có thể, ví dụ, đánh giá tác động của horsepower lên fuel efficiency thông qua hồi quy:
model <- ml_linear_regression(cars, mpg ~ hp)
Với mô hình đã huấn luyện xong chúng ta có thể sử dụng mô hình này để dự báo mức độ fuel efficiency của, ví dụ, ba quan sát với horsepower lần lượt là 250, 260 và 270 như sau:
# Some data points:
my_df <- data.frame(hp = c(250, 260, 270))
# Load to Spark environment:
my_df_spark <- copy_to(sc, my_df)
# Use trained model for predicting:
ml_predict(model, my_df_spark) -> mpg_predicted
# Show results:
mpg_predicted
## # Source: spark<?> [?? x 2]
## hp prediction
## <dbl> <dbl>
## 1 250 13.0
## 2 260 12.4
## 3 270 11.7
OK. Chúc mừng bạn. Bạn vừa sử dụng mô hình train được bằng Spark để đưa ra các giá trị dự báo lần lượt là 13.0, 12.4 và 11.7. Thực tế thì việc huấn luyện các mô hình học máy sẽ còn nhiều bước và công đoạn hơn toy example vừa trình bày ở trên. Những điều này sẽ được trình bày trong các chương sau.
More on Loading Data
Trong thực tế chúng ta thường load data một cách trực tiếp vào Spark Environment. Ví dụ với bộ data mtcars ở định dạng .csv đã được load ở trên:
load_data_to_spark <- spark_read_csv(sc, "cars.csv")
Xem dữ liệu đã load:
## # Source: spark<?> [?? x 11]
## mpg cyl disp hp drat wt qsec vs am gear carb
## <dbl> <int> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int>
## 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4
## 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4
## 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1
## 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1
## 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2
## 6 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1
Disconnecting
Sau khi xong mọi công việc chúng ta có thể kết thúc kết nối với local cluster như sau:
Nếu sử dụng nhiều culuster thì:
LS0tDQp0aXRsZTogJ01hc3RlcmluZyBBcGFjaGUgU3Bhcmsgd2l0aCBSIChDaGFwdGVyIDIpJw0KYXV0aG9yOiAnQXV0aG9yOiBOZ3V5ZW4gQ2hpIER1bmcnDQpzdWJ0aXRsZTogIlIgTWFjaGluZSBMZWFybmluZyBTZXJpZXMiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICAjIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGhpZ2hsaWdodDogemVuYnVybg0KICAgICMgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0aGVtZTogImZsYXRseSINCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCi0tLQ0KDQpgYGB7ciBzZXR1cCxpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgY2FjaGUgPSBUUlVFKQ0KDQpgYGANCg0KIVtdKEM6L1VzZXJzL0FETUlOL0RvY3VtZW50cy9wMS5qcGcpDQoNCiMgUHJlcmVxdWlzaXRlcw0KDQrEkOG7gyBz4butIGThu6VuZyDEkcaw4bujYyBBcGFjaGUgU3BhcmsgY+G6p24gY8OgaSDEkeG6t3Q6IA0KDQoxLiBDw6BpIMSR4bq3dCBbSmF2YSBKREtdKGh0dHBzOi8vd3d3Lm9yYWNsZS5jb20vamF2YS90ZWNobm9sb2dpZXMvamF2YXNlL2phdmFzZS1qZGs4LWRvd25sb2Fkcy5odG1sKS4gDQoyLiBbUl0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvYmluL3dpbmRvd3MvYmFzZS8pICsgW1IgU3R1ZGlvXShodHRwczovL3d3dy5yc3R1ZGlvLmNvbS9wcm9kdWN0cy9yc3R1ZGlvL2Rvd25sb2FkLykuIA0KMy4gVGjGsCB2aeG7h24gc3BhcmtseXIuIA0KDQpTYXUga2hpIGPDoGkgxJHhurd0IHhvbmcga2nhu4NtIHRyYSBt4buZdCBz4buRIHRow7RuZyB0aW4gduG7gSBwaGnDqm4gYuG6o246DQoNCmBgYHtyfQ0KbGlicmFyeShzcGFya2x5cikNCnNwYXJrX2luc3RhbGxlZF92ZXJzaW9ucygpDQpgYGANCg0KTmjGsCB24bqteSBTcGFyayAoVmVyc2lvbiAyLjQuMykgdsOgIEhhZG9vcCAoVmVyc2lvbiAyLjcpIGPFqW5nIMSRxrDhu6NjIGluc3RhbGwgdHLDqm4gbG9jYWwgbWFjaGluZS4gDQoNCiMgQ29ubmVjdGluZw0KDQpHaeG6oyBz4butIHLhurFuZyB2aeG7h2MgY8OgaSDEkeG6t3QgdsOgIHRoaeG6v3QgbOG6rXAgbcO0aSB0csaw4budbmcgxJHhu4Mgc+G7rSBk4bulbmcgQXBhY2hlIFNwYXJrIChn4buNaSB04bqvdCBsw6AgU3BhcmspIMSRw6MgxJHGsOG7o2MgaG/DoG4gdGjDoG5oLiBDw6FjIGNoxrDGoW5nIHNhdSBz4bq9IGdp4bqjaSB0aMOtY2ggdmnhu4djIHTDrG0sIGPDoGkgxJHhurd0IHbDoCBr4bq/dCBu4buRaSBuaGnhu4F1IFNwYXJrIENsdXN0ZXIgdHLDqm4gbmhp4buBdSBtw6F5IHTDrW5oIGtow6FjIG5oYXUuIFbhu5tpIG3hu6VjIMSRw61uaCBtaW5oIGjhu41hLCBjaMawxqFuZyBuw6B5IHThuq1wIHRydW5nIHbDoG8gduG6rW4gaMOgbmggY29kZSB0csOqbiBsb2NhbCBjbHVzdGVyIChtw6F5IHTDrW5oIGPDoSBuaMOibikuDQoNCg0KxJDhu4Mga+G6v3QgbuG7kWkgduG7m2kgbG9jYWwgY2x1c3RlciB0csOqbiBtw6F5IHTDrW5oIGPDoSBuaMOibiB0aOG7sWMgaGnhu4duIFIgY29kZXMgZMaw4bubaSDEkcOieTogDQoNCmBgYHtyfQ0Kc2MgPC0gc3BhcmtfY29ubmVjdChtYXN0ZXIgPSAibG9jYWwiLCB2ZXJzaW9uID0gIjIuNC4zIikNCmBgYA0KDQpDaMO6bmcgdGEgY8OzIHRo4buDIHhlbSB0aMOqbSBt4buZdCBz4buRIHRow7RuZyB0aW4ga2jDoWMgduG7gSBsb2NhbCBjbHVzdGVyIGLhurFuZyBs4buHbmggc2F1OiANCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpzYw0KYGBgDQoNCg0KIyBT4butIGThu6VuZyBBcGFjaGUgU3BhcmsNCg0KU2F1IGtoaSBr4bq/dCBu4buRaSB24bubaSBsb2NhbCBjbHVzdGVyIGNow7puZyB0YSBz4butIGThu6VuZyBi4buZIGThu68gbGnhu4d1ICoqbXRjYXJzKiogKGPDsyBzxINuIHRyb25nIFIgRW52aXJvbm1lbnQpIMSR4buDIG1pbmggaOG7jWEuIFRyxrDhu5tjIGjhur90IHhlbSBxdWEgYuG7mSBk4buvIGxp4buHdSBuw6B5OiANCg0KYGBge3J9DQpoZWFkKG10Y2FycykNCmBgYA0KDQpMxrB1IGzhuqFpIGLhu5kgZOG7ryBsaeG7h3UgbsOgeSDhu58gxJHhu4tuaCBk4bqhbmcgLmNzdiDEkeG7gyBz4butIGThu6VuZyBzYXUgbsOgeSBu4bq/dSBj4bqnbiB0aGnhur90OiANCg0KYGBge3J9DQp3cml0ZS5jc3YobXRjYXJzLCAiY2Fycy5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KDQpT4butIGThu6VuZyBs4buHbmggYGNvcHlfdG8oKWAgxJHhu4MgY29weSBi4buZIGThu68gbGnhu4d1IG10Y2FycyB04burIG3DtGkgdHLGsOG7nW5nIFIgdsOgbyBBcGFjaGUgU3Bhcms6IA0KDQpgYGB7cn0NCmNhcnMgPC0gY29weV90byhzYywgbXRjYXJzKQ0KYGBgDQoNCkNow7puZyB0YSBjw7MgdGjhu4MgYWNjZXNzIGLhu5kgZOG7ryBsaeG7h3UgbsOgeSB0aMO0bmcgcXVhIFIuIFbDrSBk4bulOiANCg0KYGBge3J9DQpoZWFkKGNhcnMpDQpgYGANCg0KIyBXZWIgSW50ZXJmYWNlDQoNCkjhuqd1IGjhur90IFNwYXJrIGNvbW1hbmRzIMSRxrDhu6NjIHRo4buxYyBoaeG7h24gdOG7qyBSc3R1ZGlvL1IgY29uc29sZS4gVHV5IG5oacOqbiB2aeG7h2MgdGhlbyBkw7VpICh2w6AgY8OhYyBxdcOhIHRyw6xuaCBraMOhYykgxJHGsOG7o2MgdGjhu7FjIGhp4buHbiB0aMO0bmcgcXVhIGdpYW8gZGnhu4duIFdlYiBj4bunYSBTcGFyay4gR2lhbyBkaeG7h24gIG7DoHkgbMOgIG3DtHQgd2ViIGFwcGxpY2F0aW9uIMSRxrDhu6NjIGN1bmcgY+G6pXAgYuG7n2kgU3BhcmsgYuG6sW5nIGPDoWNoIHRo4buxYyBoaeG7h24gbOG7h25oIHNhdTogDQoNCg0KYGBge3J9DQpzcGFya193ZWIoc2MpDQpgYGANCg0KS+G6v3QgcXXhuqMgc+G6vSBuaMawIGTGsOG7m2kgxJHDonk6IA0KDQohW10oQzovVXNlcnMvQURNSU4vRG9jdW1lbnRzL3AzLnBuZykNCiMgRGF0YSBRdWVyeSBhbmQgTWFuaXB1bGF0aW9uDQoNCktoaSBz4butIGThu6VuZyBTcGFyayB0aMO0bmcgcXVhIFIgY2jDum5nIHRhIGPDsyB0aOG7gyBz4butIGThu6VuZyBjw6FjIG5nw7RuIG5n4buvIHRydXkgduG6pW4gZOG7ryBsaeG7h3UuIENo4bqzbmcgaOG6oW4gc+G7rSBk4bulbmcgU1FMIMSR4buDIMSR4bq/bSBz4buRIGTDsm5nOiANCg0KYGBge3J9DQpsaWJyYXJ5KERCSSkNCmRiR2V0UXVlcnkoc2MsICJTRUxFQ1QgY291bnQoKikgRlJPTSBtdGNhcnMiKQ0KYGBgDQoNCkhv4bq3YyBz4butIGThu6VuZyBjw6FjIGjDoG0gY+G7p2EgdGjGsCB2aeG7h24gKipkcGx5cioqOiANCg0KYGBge3J9DQpsaWJyYXJ5KGRwbHlyKQ0KDQpjYXJzICU+JSANCiAgZ3JvdXBfYnkoY3lsKSAlPiUgDQogIGNvdW50KHNvcnQgPSBUUlVFKQ0KYGBgDQoNCiMgTW9kZWxsaW5nDQoNClNhdSBraGkgbG9hZCBi4buZIGThu68gbGnhu4d1IG10Y2FycyB2w6BvIFNwYXJrIEVudmlyb25tZW50IGNow7puZyB0YSBjw7MgdGjhu4MsIHbDrSBk4bulLCDEkcOhbmggZ2nDoSB0w6FjIMSR4buZbmcgY+G7p2EgaG9yc2Vwb3dlciBsw6puIGZ1ZWwgZWZmaWNpZW5jeSB0aMO0bmcgcXVhIGjhu5NpIHF1eTogDQoNCmBgYHtyfQ0KbW9kZWwgPC0gbWxfbGluZWFyX3JlZ3Jlc3Npb24oY2FycywgbXBnIH4gaHApDQpgYGANCg0KVuG7m2kgbcO0IGjDrG5oIMSRw6MgaHXhuqVuIGx1eeG7h24geG9uZyBjaMO6bmcgdGEgY8OzIHRo4buDIHPhu60gZOG7pW5nIG3DtCBow6xuaCBuw6B5IMSR4buDIGThu7EgYsOhbyBt4bupYyDEkeG7mSBmdWVsIGVmZmljaWVuY3kgY+G7p2EsIHbDrSBk4bulLCBiYSBxdWFuIHPDoXQgduG7m2kgaG9yc2Vwb3dlciBs4bqnbiBsxrDhu6N0IGzDoCAyNTAsIDI2MCB2w6AgMjcwIG5oxrAgc2F1OiANCg0KYGBge3J9DQojIFNvbWUgZGF0YSBwb2ludHM6IA0KbXlfZGYgPC0gZGF0YS5mcmFtZShocCA9IGMoMjUwLCAyNjAsIDI3MCkpDQoNCiMgTG9hZCB0byBTcGFyayBlbnZpcm9ubWVudDogDQpteV9kZl9zcGFyayA8LSBjb3B5X3RvKHNjLCBteV9kZikNCg0KIyBVc2UgdHJhaW5lZCBtb2RlbCBmb3IgcHJlZGljdGluZzogDQptbF9wcmVkaWN0KG1vZGVsLCBteV9kZl9zcGFyaykgLT4gbXBnX3ByZWRpY3RlZA0KDQojIFNob3cgcmVzdWx0czogDQptcGdfcHJlZGljdGVkIA0KYGBgDQoNCk9LLiBDaMO6YyBt4burbmcgYuG6oW4uIELhuqFuIHbhu6thIHPhu60gZOG7pW5nIG3DtCBow6xuaCB0cmFpbiDEkcaw4bujYyBi4bqxbmcgU3BhcmsgxJHhu4MgxJHGsGEgcmEgY8OhYyBnacOhIHRy4buLIGThu7EgYsOhbyBs4bqnbiBsxrDhu6N0IGzDoCAxMy4wLCAxMi40IHbDoCAxMS43LiBUaOG7sWMgdOG6vyB0aMOsIHZp4buHYyBodeG6pW4gbHV54buHbiBjw6FjIG3DtCBow6xuaCBo4buNYyBtw6F5IHPhur0gY8OybiBuaGnhu4F1IGLGsOG7m2MgdsOgIGPDtG5nIMSRb+G6oW4gaMahbiB0b3kgZXhhbXBsZSB24burYSB0csOsbmggYsOgeSDhu58gdHLDqm4uIE5o4buvbmcgxJFp4buBdSBuw6B5IHPhur0gxJHGsOG7o2MgdHLDrG5oIGLDoHkgdHJvbmcgY8OhYyBjaMawxqFuZyBzYXUuIA0KDQojIE1vcmUgb24gTG9hZGluZyBEYXRhDQoNClRyb25nIHRo4buxYyB04bq/IGNow7puZyB0YSB0aMaw4budbmcgbG9hZCBkYXRhIG3hu5l0IGPDoWNoIHRy4buxYyB0aeG6v3AgdsOgbyBTcGFyayBFbnZpcm9ubWVudC4gVsOtIGThu6UgduG7m2kgYuG7mSBkYXRhIG10Y2FycyDhu58gxJHhu4tuaCBk4bqhbmcgLmNzdiDEkcOjIMSRxrDhu6NjIGxvYWQg4bufIHRyw6puOiANCg0KYGBge3J9DQpsb2FkX2RhdGFfdG9fc3BhcmsgPC0gc3BhcmtfcmVhZF9jc3Yoc2MsICJjYXJzLmNzdiIpDQpgYGANCg0KWGVtIGThu68gbGnhu4d1IMSRw6MgbG9hZDogDQoNCmBgYHtyfQ0KaGVhZChsb2FkX2RhdGFfdG9fc3BhcmspDQpgYGANCg0KIyBEaXNjb25uZWN0aW5nDQoNClNhdSBraGkgeG9uZyBt4buNaSBjw7RuZyB2aeG7h2MgY2jDum5nIHRhIGPDsyB0aOG7gyBr4bq/dCB0aMO6YyBr4bq/dCBu4buRaSB24bubaSBsb2NhbCBjbHVzdGVyIG5oxrAgc2F1OiANCg0KYGBge3J9DQpzcGFya19kaXNjb25uZWN0KHNjKQ0KYGBgDQoNCk7hur91IHPhu60gZOG7pW5nIG5oaeG7gXUgY3VsdXN0ZXIgdGjDrDogDQoNCmBgYHtyfQ0Kc3BhcmtfZGlzY29ubmVjdChzYykNCmBgYA0KDQoNCg0KDQoNCg0KDQoNCg==