Mô hình tính toán
MapReduce

MapReduce đưa mọi cặp cùng khóa về một tác vụ Reduce; đổi lại, dữ liệu trung gian phải được chuyển đi.

Giải thuật nền tảng của Khoa học dữ liệu

Học kỳ 1 · Năm học 2026–2027

Trường Đại học Công nghệ · Đại học Quốc gia Hà Nội

Tiên quyết và quy ước

Nhắc lại: phép toán, bộ nhớ, đọc ghi, truyền mạng tính riêng.

Nhắc lại: thuật toán đúng khi khớp đặc tả; chứng minh bằng bất biến.

Nhắc lại: cộng số nguyên (không tràn) kết hợp, giao hoán.

Ký hiệu: \(n\) cỡ đầu vào; \(P\) số máy; chữ trùng chỉ có nghĩa trong mạch dùng.

Quy ước: dấu phẩy thập phân; 1 MB = \(10^6\) byte.

Mục tiêu học tập

  1. Viết Map, Reduce cho bài đếm từ; chạy tay qua pha nhóm theo khóa.
  2. Nêu điều kiện để Combine giữ nguyên kết quả; chỉ ra một phép gộp không thỏa.
  3. Chọn khóa, giá trị trung gian và chứng minh tính đúng cho ba bài toán gộp.
  4. Tính công việc, thời gian các pha, lượng truyền và mức tăng tốc.
  5. Chạy đếm từ trên cụm Hadoop; đối chiếu kết quả và bộ đếm với chạy tay.

Nội dung

  1. Xử lý dữ liệu trên cụm máy
  2. Mô hình tính toán MapReduce
  3. Các ví dụ MapReduce
  4. Chi phí và lợi ích của song song hóa
  1. Hệ thống thực thi MapReduce Đọc thêm
  2. Thực hành Hadoop với Docker Compose
  3. Tổng kết và bài tập vận dụng

Đọc trước: Leskovec, Rajaraman, Ullman, Mining of Massive Datasets (MMDS), ấn bản 3, Chương 2, §§2.1–2.3, §2.5.

Vấn đề trung tâm

Nhu cầu: đếm từ trên kho nằm ở nhiều máy.

  • Map, nhóm theo khóa, Reduce: đúng khi hàm xác định, Reduce không phụ thuộc thứ tự.
  • Gộp cục bộ đúng khi phép gộp kết hợp, giao hoán, giữ đủ thông tin.
  • Thêm máy rút ngắn thời gian khi truyền, gộp không lấn át.
  • Cụm Hadoop khớp số đếm tính tay.

Dữ liệu lớn trên nhiều máy

Quy mô dữ liệu Google, 1998–2005.

Dữ liệu chia thành khối A, B, C; máy 1 lưu A và B, máy 2 lưu B và C, máy 3 lưu C và A. Mỗi khối có hai bản sao trên các máy khác nhau.
Bài toánQuy môĐầu ra
Lập chỉ mụchơn 8 tỷ trang (2004)trang chứa từng từ
Đếm truy vấn450 GB nhật ký nén (2005)số truy vấn theo ngày
Liên kết đến24 triệu trang, hơn 259 triệu liên kết (1998)trang trỏ tới từng trang

Kết luận: dữ liệu ở nhiều máy, các máy phải cùng xử lý.

Bốn yêu cầu của mô hình tính toán

1

Dữ liệu nằm trên nhiều máy

Xử lý từng phần ở nơi lưu.

2

Song song hóa tính toán

Các máy làm đồng thời.

3

Đưa tính toán đến gần dữ liệu

Giảm truyền qua mạng.

4

Điều phối và phục hồi tự động

Hệ thống chia việc, lập lịch, chạy lại.

Ví dụ: cộng sáu số trên ba máy

Tính \(S=a_1+\cdots+a_6\); mỗi máy cộng hai số tại chỗ, rồi gộp ba tổng.

Máy 1

\(s_1=a_1+a_4\)

Máy 2

\(s_2=a_2+a_5\)

Máy 3

\(s_3=a_3+a_6\)

Ba tổng cục bộ được chuyển tới bước gộp

Gộp kết quả: \(S=s_1+s_2+s_3\)

Giao hoán

Đổi thứ tự các số

Kết hợp

Đổi cách nhóm

Kết luận: thay \(+\) bằng \(\oplus\) giao hoán, kết hợp vẫn tính tại từng máy rồi gộp được.

Giả thiết: phép toán chính xác; mỗi số được tính đúng một lần.

Cụm máy và lưu trữ phân tán HDFS

Hệ thống tệp phân tán Hadoop (HDFS) chia tệp thành khối và lưu nhiều bản sao.

Hai rack nối mạng, mỗi rack có hai máy qua bộ chuyển mạch. A ở máy 1, 3, 4; B ở máy 1, 2, 3. Mỗi rack đều có đủ A và B.

Cục bộ hóa tính toán

Ưu tiên máy có khối, rồi máy cùng rack, rồi rack khác.

Chịu lỗi nhờ bản sao

Mất một máy hoặc một rack vẫn còn A và B; HDFS sao chép lại bản thiếu.

2.Mô hình tính toán MapReduce

Muốn đếm từ trên kho nằm ở nhiều máy, phải đặc tả hai hàm Map, Reduce và phép nhóm theo khóa.

Map · Reduce · Nhóm theo khóa · Các pha · Combine

Bốn cơ chế của MapReduce

Ba máy nối mạng, mỗi máy lưu một phần dữ liệu

Xử lý dữ liệu phân tán

Mỗi Map nhận một phần đầu vào.

Ba tác vụ tiến hành đồng thời

Tính toán song song

Map độc lập; Reduce chạy theo khóa.

Phép tính và dữ liệu nằm trong cùng một máy

Tính toán gần dữ liệu

Giao Map cho máy giữ khối.

Tác vụ được chuyển từ máy lỗi sang máy khác để chạy lại

Điều phối và phục hồi tự động

Chạy lại tác vụ máy hỏng.

Kết luận: người lập trình viết hai hàm; hệ thống thực thi.

Bài toán đếm từ

Nhu cầu: kho vượt bộ nhớ một máy; cùng từ ở nhiều máy phải gộp số đếm.

Đầu vào

$n$ văn bản đã tách từ thống nhất; $V$ là tập từ xuất hiện.

Đầu ra

Mỗi $w\in V$ một cặp $(w,c(w))$.

Gọi $c_i(w)$ là số lần từ $w$ xuất hiện trong $d_i$. Với $w\in V$:

$c(w) = \sum_{i=1}^{n} c_i(w)$

Tập văn bản

$d_1$
$d_2$
…
$d_n$
TừSố lần
$w$$c(w)$

Mỗi từ một số đếm.

Thuật toán: Map và Reduce cho đếm từ

Hàm Map

Đầu vào: văn bản $d_i$; đầu ra: một cặp $(w,1)$ mỗi lần xuất hiện.

Map(d_i):
  với mỗi lần từ w xuất hiện trong d_i:
      phát(w, 1)

Hàm Reduce

Đầu vào: từ $w$ và danh sách $L_w$; đầu ra: $(w,c(w))$.

Reduce(w, L_w):
  c = 0
  với mỗi giá trị v trong L_w:
      c = c + v
  phát(w, c)

Hệ thống gom mọi giá trị cùng từ $w$ vào $L_w$; khóa là từ, giá trị 1 là một lần xuất hiện.

Phân phối tác vụ trên cụm máy

Tiến trình điều phối (Master) giao tác vụ cho máy rảnh, ưu tiên nơi có dữ liệu.

Tác vụ Map

Tác vụ Map 1 · Máy 1
Tác vụ Map 2 · Máy 2
Tác vụ Map 3 · Máy 3

Chuyển và nhóm theo từ:
cùng từ thì cùng tác vụ Reduce.

Tác vụ Reduce

Tác vụ Reduce 1 · Máy 1
Tác vụ Reduce 2 · Máy 3

Ví dụ: đếm từ trong hai văn bản

Map: phát (từ, 1)

$d_1$ = "mèo chó mèo"

  • (mèo, 1)
  • (chó, 1)
  • (mèo, 1)

$d_2$ = "chó chim"

  • (chó, 1)
  • (chim, 1)

Nhóm theo từ

  • mèo: $[1, 1]$
  • chó: $[1, 1]$
  • chim: $[1]$

Reduce: cộng từng nhóm

  • (mèo, 2)
  • (chó, 2)
  • (chim, 1)

Kiểm tra: $2+2+1=5$ lần.

Hàm Map

Định nghĩa. Map biến một cặp đầu vào thành dãy cặp trung gian:

$\mathrm{Map}:K_1\times V_1\longrightarrow(K_2\times V_2)^*$

$K_1,V_1$ là miền đầu vào; $K_2,V_2$ là miền trung gian.

$A^*$ là tập dãy hữu hạn trên $A$, gồm dãy rỗng, giữ phần tử lặp.

Một văn bản

$(1,d_1)$

“mèo chó mèo”

→
Map
→
Các cặp được phát

(mèo, 1), (chó, 1), (mèo, 1)

Ý nghĩa: một lần gọi Map phát không, một hoặc nhiều cặp.

Hàm Reduce

Định nghĩa. Hàm Reduce nhận một khóa cùng danh sách giá trị và phát một dãy cặp:

$\mathrm{Reduce}:K_2\times V_2^*\longrightarrow(K_3\times V_3)^*$

$L_k$ là danh sách giá trị đi cùng khóa $k$, do hệ thống cung cấp; $K_3,V_3$ là miền đầu ra.

Đếm từ: một nhóm

mèo, [1, 1]

→
Reduce
→
Dãy cặp kết quả

[(mèo, 2)]

Giả thiết: Reduce không phụ thuộc thứ tự các giá trị trong $L_k$.

Phân phối và nhóm theo khóa

$I$ là dãy cặp trung gian theo một thứ tự tùy chọn; giữ mọi lần lặp:

$L_k=[\,v\mid(k',v)\in I,\ k'=k\,]$

Hàm phân phối $p:K_2\to\{0,\ldots,r-1\}$ gán mỗi khóa cho một trong $r\geq1$ tác vụ Reduce.

Trích các cặp từ $I$

(mèo, 1), (chó, 1)
(mèo, 1), (chó, 1)

→
Hai nhóm riêng

mèo: [1, 1]
chó: [1, 1]

→
Tác vụ Reduce 0

Reduce(mèo), Reduce(chó)

Kết luận: cùng khóa thì cùng tác vụ; khác khóa vẫn nhóm riêng.

Các pha của một công việc MapReduce

$X$ là dãy cặp đầu vào; $m\geq1$ là số tác vụ Map; $Y$ là dãy cặp đầu ra.

1 · Chia đầu vào

$B_1,\ldots,B_m$

Hệ thống chia
→

2 · Map

Các cặp trung gian $I$

Người lập trình viết
→

3 · Phân phối
và nhóm

Các nhóm $(k,L_k)$

Hệ thống thực hiện
→

4 · Reduce

Các cặp kết quả $Y$

Người lập trình viết

Thuật toán: một công việc MapReduce

Đầu vào: $X$, Map, Reduce, $m,r\geq1$, hàm phân phối $p$.

Đầu ra: dãy cặp $Y$, không quy định thứ tự.

khởi tạo O_0, ..., O_{r−1} là các dãy rỗng
chia X thành B_1, ..., B_m theo vị trí bản ghi
song song với j = 1, ..., m:
  I_j ← gom_giữ_lặp(Map(k,v) với mỗi (k,v) trong B_j)
I ← gom_giữ_lặp(I_1, ..., I_m)
song song với t = 0, ..., r−1:
  với mỗi khóa phân biệt k xuất hiện trong I và p(k) = t:
    L_k ← danh sách các v đi cùng k trong I
    ghi mọi cặp Reduce(k,L_k) vào O_t
trả về Y = gom_giữ_lặp(O_0, ..., O_{r−1})

Thao tác quyết định: nhóm $I$ theo khóa, giao $L_k$ cho tác vụ $p(k)$; gom_giữ_lặp giữ mọi phần tử.

Tính đúng: một công việc MapReduce

Giả thiết: hàm xác định, dừng; Reduce không phụ thuộc thứ tự.

Mệnh đề. $Y$ gồm đúng các cặp $\mathrm{Reduce}(k,L_k)$, mỗi khóa $k$ của $I$ một lần.

  1. Mỗi vị trí thuộc một $B_j$; gom_giữ_lặp giữ đủ.
  2. Mỗi khóa $k$ có một $p(k)$, nên một nhóm $L_k$.
  3. Không phụ thuộc thứ tự: $\mathrm{Reduce}(k,L_k)$ xác định.

Trường hợp biên: $X$ rỗng thì $Y$ rỗng; mọi dãy hữu hạn nên công việc dừng.

Gộp cục bộ bằng hàm Combine

Nhu cầu: Map 1 phát hai cặp (mèo, 1); gộp tại chỗ để gửi ít hơn.

Hàm Combine (combiner) gộp giá trị cùng khóa ở phía Map.

Các cặp do Map phátSau Combine tại từng tác vụ Map Map 1: (mèo, 1), (chó, 1), (mèo, 1)(mèo, 2), (chó, 1)→ Map 2: (chó, 1), (chim, 1)(chó, 1), (chim, 1)→

5 cặp còn 4 qua mạng; Reduce vẫn cho mèo 2, chó 2, chim 1.

Giả thiết: phép gộp kết hợp, giao hoán; giữ khóa, kiểu giá trị.

Kết luận: bỏ Combine hay gộp nhiều lần, kết quả không đổi.

Câu hỏi về mô hình MapReduce

$d_1$ = “mèo chó mèo”, $d_2$ = “chó chim”; mỗi văn bản một Map; Combine, Reduce cộng.

Câu hỏi:

  1. Sau Combine, mỗi tác vụ Map gửi những cặp nào?
  2. Reduce nhận danh sách nào cho khóa "chó", trả kết quả gì?
  3. Hai khóa khác nhau có thể cùng một tác vụ Reduce không?
  4. Một máy có thể chạy nhiều tác vụ không?

3.Các ví dụ MapReduce

Muốn áp mô hình cho bài toán mới, phải chọn khóa và giá trị trung gian đủ để gộp đúng.

Nhân ma trận–véc tơ · Đếm từ phân biệt · Trung bình cộng · Tính đúng

Bài toán nhân ma trận–véc tơ

Đầu vào: $A\in\mathbb{R}^{p\times q}$, $v\in\mathbb{R}^q$, với $p,q\geq1$.

Đầu ra: véc tơ $y=Av\in\mathbb{R}^p$, gồm $p$ phần tử:

$y_i=\sum_{j=1}^{q}a_{ij}v_j,\qquad 1\leq i\leq p$

Dữ liệu logic: $pq$ bản ghi $(i,j,a_{ij})$, kể cả phần tử 0.

Giả thiết: $v$ vừa bộ nhớ mỗi tác vụ Map; số học chính xác.

Điểm tương đồng của trang web với truy vấn

$A$ có $p$ hàng là trang web, $q$ cột là từ; phần tử là trọng số của từ.

$v$ là trọng số của $q$ từ ấy trong truy vấn.

Với các véc tơ khác 0, chuẩn hóa từng hàng của $A$ và $v$ về độ dài Euclid 1.

$y=Av,\qquad y_i=\sum_{j=1}^{q}a_{ij}v_j$

A: p trang × q từ × v: truy vấn (q chiều) = y: điểm cosin từng trang

Ý nghĩa: $y_i$ là điểm tương đồng cosin của trang $i$ với truy vấn.

Nhân ma trận–véc tơ theo khối

  1. Ma trận chia thành các khối; mỗi khối có bản sao trên nhiều máy.
  2. Map nhận một khối $B$, duyệt từng bản ghi và tra $v_j$ để tính tích.
  3. Các đóng góp cùng hàng được gom về một khóa.
Máy 1B1B2Máy 2B2B3Máy 3B3B1
Ba khối B1, B2, B3; mỗi khối có hai bản sao trong hình.

Thuật toán: nhân ma trận–véc tơ

Đầu vào: khối $B$ gồm bản ghi $(i,j,a_{ij})$; $v$ có trong bộ nhớ.

Đầu ra: các cặp $(i,y_i)$; $L$ chứa các giá trị cùng hàng.


Map(B):
  với mỗi bản ghi (i, j, a_ij) trong B:
    yield(i, a_ij * v[j])
Combine(i, L): yield(i, sum(L))
Reduce(i, L):  yield(i, sum(L))
Khóa là hàng \( i \); giá trị là tích \( a_{ij} v_j \) hoặc tổng bộ phận của các tích.

Ví dụ: ma trận 4×4 chia bốn khối

Bốn khối $2\times2$: $B_{11},B_{12}$ ở trên; $B_{21},B_{22}$ ở dưới; ma trận chưa chuẩn hóa.

$A=\left[\begin{array}{cc|cc}1&2&0&1\\0&1&2&0\\\hline2&0&1&1\\1&1&0&2\end{array}\right],\quad v=\begin{bmatrix}1\\2\\3\\4\end{bmatrix}$

Bản ghi $(2,3,2)$ → yield(2, 2*3) → $(2,6)$.

KhốiCác cặp Map phátCombine phát
$B_{11}$(1,1), (1,4)
(2,0), (2,2)
(1,5)
(2,2)
$B_{12}$(1,0), (1,4)
(2,6), (2,0)
(1,4)
(2,6)
$B_{21}$(3,2), (3,0)
(4,1), (4,2)
(3,2)
(4,3)
$B_{22}$(3,3), (3,4)
(4,0), (4,8)
(3,7)
(4,8)

Kết luận: Reduce cộng theo hàng: $5+4=9$, $2+6=8$, $2+7=9$, $3+8=11$; $y=(9,8,9,11)^T$.

Tính đúng: nhân ma trận–véc tơ

Mệnh đề. Với mọi hàng $1\leq i\leq p$, đầu ra bằng $y_i=\sum_{j=1}^{q}a_{ij}v_j$.

  1. Mỗi tọa độ thuộc đúng một khối; Map phát mỗi tích $a_{ij}v_j$ đúng một lần.
  2. Khóa $i$ gom đúng $q$ tích của hàng $i$, giữ cả tích 0.
  3. Combine bảo toàn tổng (cộng kết hợp, giao hoán), nên Reduce trả $y_i$.

Kết luận: cả $p$ hàng đều đúng nên $y=Av$.

Bài toán đếm từ phân biệt

Nhu cầu: “mèo chó mèo” và “chó chim” có 2 và 2 từ phân biệt, nhưng toàn kho chỉ có 3.

Đầu vào: $n\geq1$ văn bản $d_1,\ldots,d_n$ đã tách từ nhất quán; $W_i$ là tập từ của $d_i$.

Đầu ra: số từ phân biệt trong toàn bộ các văn bản:

$D=\left|\bigcup_{i=1}^{n}W_i\right|$

Trường hợp biên: mọi văn bản rỗng thì $D=0$.

Kích thước từ vựng của kho trang web

Biểu diễn kho trang web theo từ: cần biết có bao nhiêu từ khác nhau.

Kho n trang web → Từ duy nhất (đại diện) → D = q cột
“mèo chó mèo” và “chó chim” có ba từ: mèo, chó, chim.

$D=3\quad\Longrightarrow\quad q=3$ cột

Khi dùng toàn bộ từ vựng của kho, mỗi từ khác nhau tương ứng một chiều.

Đếm từ phân biệt bằng hai công việc

Nhu cầu: từ lặp trong và giữa các văn bản; cộng số từ phân biệt cục bộ đếm trùng.

  1. Công việc 1: nhóm theo từ $w$, giữ một cặp $(w,1)$ cho mỗi từ hiện diện.
  2. Công việc 2: đếm các cặp ấy bằng khóa chung $g$.
Từ ở nhiều văn bảnMột cặp cho mỗi từĐếm với khóa chung g

$g$ là nhãn cố định để gom số đếm, không phải một từ.

Thuật toán: đếm từ phân biệt

Đầu vào: $n$ văn bản; công việc 2 nhận đầu ra công việc 1.

Đầu ra: $(g,D)$; $L$ là danh sách giá trị cùng khóa, khác rỗng.

HàmCông việc 1: loại trùngCông việc 2: đếm
MapVới mỗi lần từ $w$ xuất hiện trong $d_i$, phát $(w,1)$.Nhận $(w,1)$, phát $(g,1)$.
CombineNhận $(w,L)$, phát một cặp $(w,1)$.Nhận $(g,L)$, phát $(g,\sum_{v\in L}v)$.
ReduceNhận $(w,L)$, phát một cặp $(w,1)$.Nhận $(g,L)$, phát $(g,\sum_{v\in L}v)$.

Trường hợp biên: không có từ thì chương trình chính (driver) trả 0.

Ví dụ: đếm từ phân biệt trong hai văn bản

\( d_1 \) = “mèo chó mèo”, \( d_2 \) = “chó chim”.

BướcDữ liệu
Map phát 5 cặp(mèo,1), (chó,1), (mèo,1) từ d1; (chó,1), (chim,1) từ d2
Combine 1 từng Mapd1: mèo 1, chó 1; d2: chó 1, chim 1
Công việc 1 Reducemèo [1] → mèo 1; chó [1, 1] → chó 1; chim [1] → chim 1
Công việc 2Map phát (g,1) ba lần → nhóm [1,1,1] → Reduce (g,3)

Kết luận: 3 từ phân biệt, 5 lần xuất hiện; cộng cục bộ \(2+2=4\) sai.

Tính đúng: đếm từ phân biệt

Mệnh đề. Giá trị cuối bằng \( D \).

  1. Mỗi từ xuất hiện có cặp Map; công việc 1 giữ đúng một cặp \( (w,1) \).
  2. Từ không xuất hiện không sinh cặp.
  3. Công việc 2: mỗi cặp góp một số 1 vào \( g \), nên giá trị cuối là \( D \).

Trường hợp biên: mọi văn bản rỗng thì không có cặp; trả 0.

Bài toán trung bình cộng

Nhu cầu: [2, 4] có trung bình 3, [9] có trung bình 9; trung bình của 3 và 9 là 6, của cả dãy là 5.

Đầu vào: dãy $a_1,\ldots,a_n\in\mathbb{R}$, với $n\geq1$.

Đầu ra: trung bình cộng của toàn bộ dãy:

$\mu=\frac{1}{n}\sum_{i=1}^{n}a_i$

Giả thiết: số học chính xác; dãy rỗng không có trung bình.

Số từ trung bình mỗi trang

Với $n\geq1$ trang web, $a_i$ là số từ của trang $i$, tính cả từ lặp.

Hai trang “mèo chó mèo” và “chó chim” có lần lượt 3 và 2 từ.

3 từ và 2 từ → Tổng = 5; số trang = 2 → 2,5 từ / trang

$\mu=\frac{3+2}{2}=2{,}5$ từ/trang

Cần biết cả tổng số từ và số trang trước khi chia.

Trạng thái tổng và số lượng

  1. Trung bình từng phần bỏ mất kích thước: [2, 4] có 2 phần tử, [9] có 1.
  2. Giữ trạng thái \( (s,c) \) với \( s \) là tổng, \( c \) là số lượng.
Trạng thái (s, c)Cộng tổng và số lượngChia tổng cho số lượng

Thuật toán: trung bình cộng

Đầu vào: $a_1,\ldots,a_n$, $n\geq1$; khóa chung $g$.

Đầu ra: $(g,\mu)$; $L$ là danh sách các trạng thái $(s,c)$.

$S=\sum_{(s,c)\in L}s$, $C=\sum_{(s,c)\in L}c$: cộng từng thành phần, giữ mọi lần lặp.

HàmĐầu vào → cặp được phátKiểu giá trị phát
Map$a_i\ \longrightarrow\ (g,(a_i,1))$Cặp (tổng, số lượng)
Combine$(g,L)\ \longrightarrow\ (g,(S,C))$Cặp (tổng, số lượng)
Reduce$(g,L)\ \longrightarrow\ (g,S/C)$Một số

Kết luận: Combine giữ tổng và số lượng; chỉ Reduce chia.

Ví dụ: trung bình của 2, 4, 9

Map 1 nhận \( [2, 4] \), Map 2 nhận \( [9] \); tổng cộng \( n = 3 \).

BướcDữ liệu
Map 1phát (g, (2,1)), (g, (4,1)) → Combine phát (g, (6, 2))
Map 2phát (g, (9,1)) → Combine phát (g, (9, 1))
ReduceL = [(6, 2), (9, 1)] → S = 15, C = 3 → phát (g, 5)

Kết luận: \( \mu = 15 / 3 = 5 \); Combine chỉ cộng hai thành phần, không chia.

Tính đúng: trung bình cộng

Bất biến: mỗi cặp \( (s,c) \) là tổng và số vị trí gốc của một nhóm phần tử rời nhau.

Khởi tạoDuy trìKết thúc
Map phát \( (a_i,1) \).Gộp nhóm rời nhau: cộng hai thành phần.\( S=\sum_i a_i \), \( C=n>0 \), nên \( S/C=\mu \).

Kết luận: có hay không Combine, kết quả không đổi.

Câu hỏi về ba ví dụ

Câu hỏi:

  1. Trong nhân ma trận–véc tơ, vì sao khóa là hàng \( i \) chứ không phải cột \( j \)?
  2. Với \( d_1 \) = “mèo chó mèo”, \( d_2 \) = “chó chim”: cộng số từ phân biệt từng văn bản có ra số toàn bộ không?
  3. Có thể dùng Reduce của bài trung bình làm Combine không? Nếu không, cần giữ gì?

4.Chi phí và lợi ích của song song hóa

Muốn biết thêm máy có rút ngắn thời gian hay không, phải đếm công việc, thời gian từng pha và lượng truyền.

Tổng công việc · Thời gian hoàn thành · Lượng truyền · Combine · Mức tăng tốc

Ba đại lượng chi phí

Nhu cầu: so sánh các cách chạy trên nhiều máy.

W

W: tổng phép toán

TP: thời gian, giây

V: byte qua mạng

Ký hiệu: \(P\) là số máy giống nhau; \(p\) vẫn là số hàng ma trận.

Ví dụ: số phép cộng khi cộng 16 số

Đếm số phép cộng; khởi tạo tổng bằng phần tử đầu.

a₁ a₂ a₃ … a₁₆ 1 máy: 15 phép cộng
a₁…a₄ a₅…a₈ a₉…a₁₂ a₁₃…a₁₆ Bốn máy: 4 × 3 = 12 phép cộng gộp 4 tổng: 3 phép cộng tổng: 15 phép cộng

Kết luận: bốn máy vẫn làm \(4\cdot3+3=15\) phép cộng, bằng một máy.

Chi phí: cộng một dãy số

Mô hình: chỉ đếm phép cộng; khởi tạo tổng bằng phần tử đầu.

BướcSố lầnChi phí mỗi lầnĐóng góp
Cộng cục bộ\(P\) máy\(n/P-1\)\(P(n/P-1)\)
Gộp tổng cục bộ1\(P-1\)\(P-1\)
Tổng\(W_P=n-1\)

Giả thiết: \(n\geq P\geq1\), \(P\) chia hết \(n\), số học chính xác.

Chi phí: thời gian của một pha

Mô hình: mọi tác vụ sẵn sàng từ 0; mỗi máy chạy lần lượt, không nghỉ, không lỗi.

Ba máy chạy từ thời điểm 0. Máy 1: A và B, mỗi tác vụ 2 giây; máy 2: C và D, mỗi tác vụ 3 giây; máy 3: E dài 3 giây. Pha kết thúc ở giây 6.

Gọi \(t_m\) là tổng thời gian các tác vụ giao cho máy \(m\).

\( T_{\text{pha}} = \max_m t_m = \max(4,\,6,\,3) = 6\,\text{s} \)

Ví dụ: thời gian cộng 16 số trên bốn máy

\(\tau>0\): thời gian một phép cộng; mỗi máy nhận 4 số.

Mô hình: hai pha nối tiếp; bỏ đọc ghi, truyền, điều phối.

Cùng trục thời gian: một máy cộng 16 số trong 15 tau. Bốn máy cùng Map cộng cục bộ từ 0 đến 3 tau, sau đó Reduce trên máy 1 gộp từ 3 đến 6 tau. Các thanh và mốc dùng 60 pixel cho một tau.

\(T_{\text{Map}}=3\tau,\qquad T_{\text{Reduce}}=3\tau\)
\(T_4=T_{\text{Map}}+T_{\text{Reduce}}=3\tau+3\tau=6\tau\)

Giả thiết: dữ liệu đã nằm tại mỗi máy; một tác vụ Reduce gộp tuần tự bốn tổng.

Chi phí: tổng đầu vào tác vụ

Nhu cầu: so hai cách tổ chức tác vụ theo lượng dữ liệu đọc.

Mô hình: chi phí tác vụ là kích thước đầu vào; \(C\) là tổng mọi tác vụ.

\(I\) là tổng dữ liệu gốc các Map đọc; \(H\) là tổng dữ liệu trung gian các Reduce nhận.

Đầu vào Map I bằng 100 MB đi vào các tác vụ Map; 40 MB trung gian H đi vào Reduce; đầu ra cuối không được cộng vào chi phí C theo quy ước sách.

\( C = I + H = 100 + 40 = 140\,\text{MB} \)

Giả thiết: một công việc, không chạy lại; Combine nằm trong Map.

Chi phí: thời gian truyền một thông điệp

Mô hình: \(V\) là lượng truyền (MB), \(B\) là băng thông (MB/s), \(\lambda\) là độ trễ khởi đầu (giây).

Thông điệp V = 100 MB 1 đường truyền B = 50 MB/s λ = 0,02 s Máy nhận chờ 2,02 s

Thời gian truyền \(T\) gồm độ trễ khởi đầu và thời gian chuyển \(V\) với tốc độ \(B\):

\( T \approx \lambda + \dfrac{V}{B} = 0{,}02 + \dfrac{100}{50} = 2{,}02\,\text{s} \)

Giả thiết: một thông điệp, băng thông ổn định; 1 MB là \(10^6\) byte.

Chi phí: đường nối dùng chung

100 MB/s là băng thông của cả đường nối dùng chung: nhiều máy cùng gửi thì phải chia sẻ.

Bốn máy trong rack gửi, mỗi máy 100 MB; tất cả 400 MB qua một đường nối 100 MB mỗi giây tới máy nhận trong rack khác.

\( T \geq \dfrac{V}{B} = \dfrac{400}{100} = 4\,\text{s} \)

T là thời gian chuyển đủ 400 MB: cần ít nhất 4 giây, chưa kể độ trễ.

Kết luận: xử lý gần dữ liệu giảm số byte qua đường nối này.

Chi phí: lượng truyền khi có Combine

\( d_1 \) = “mèo chó mèo”, \( d_2 \) = “chó chim”.

Phương ánCặp đi qua đường truyềnV (mỗi cặp 16 byte)
Không Combine
(5 cặp)
d₁: (mèo,1), (chó,1), (mèo,1)
d₂: (chó,1), (chim,1)
5 × 16 = 80 byte
Có Combine
(4 cặp)
d₁: (mèo,2), (chó,1)
d₂: (chó,1), (chim,1)
4 × 16 = 64 byte

Kết luận: lượng truyền giảm từ 80 còn 64 byte (20%), đổi lại Map cộng thêm.

Giả thiết: mỗi văn bản một Map; mỗi cặp 16 byte, qua đường truyền một lần.

Chi phí: thời gian của cả công việc

\(T_P\) là thời gian từ lúc bắt đầu đến khi có đủ kết quả trên \(P\) máy.

Ví dụ giả định, \(P=4\): bốn pha điều phối, Map, truyền và nhóm, Reduce.

Bốn pha nối tiếp: điều phối từ 0 đến 1 giây, Map từ 1 đến 5 giây, truyền và nhóm từ 5 đến 8 giây, Reduce từ 8 đến 10 giây.

\( T_P = 1+4+3+2 = 10\,\text{s} \)

Mô hình: mỗi pha kết thúc khi máy cuối cùng xong; các pha nối tiếp, không lỗi.

Mức tăng tốc

Mức tăng tốc \(S_P\) là tỷ số \(T_1/T_P\), với \(T_1\) là thời gian trên một máy.

Cùng công việc: một máy 24 giây, bốn máy 10 giây. Hai thanh dùng chung thang thời gian, tỷ lệ 2,4.

\( S_P = \dfrac{T_1}{T_P}, \qquad S_4 = \dfrac{24}{10} = 2{,}4 \)

Kết luận: với dữ kiện này, bốn máy nhanh hơn một máy 2,4 lần.

Giả thiết: cùng đầu vào, cùng đầu ra, cùng phạm vi đo thời gian.

Câu hỏi về thời gian và mức tăng tốc

Đại lượngDữ kiện
Điều phối1s
Thời gian Map mỗi máy
(P = 3)
2s / 3s / 5s
Lượng truyền V120 MB
Băng thông B40 MB/s
Reduce2s
Tuần tự T₁22s

Giả thiết: các pha nối tiếp; bỏ độ trễ, chi phí nhóm.

Câu hỏi:

  1. Tính TMap và Ttruyền.
  2. Tính TP và SP.
  3. Combine giảm V còn 40 MB, Map tăng 1 s: tính T′P và thời gian tiết kiệm.

5.Hệ thống thực thi MapReduce

Muốn hiểu thời gian chạy và cách phục hồi, phải theo dữ liệu từ phần đầu vào qua Shuffle tới Reduce.

Phần đầu vào · HDFS · Hàm phân phối · Shuffle · Phục hồi khi máy hỏng

Phần đầu vào và tác vụ Map

Đọc thêm

Nhu cầu: thời gian chạy phụ thuộc cách giao tác vụ và chuyển dữ liệu.

Phần đầu vào (InputSplit) xác định dữ liệu một tác vụ Map phải đọc.

Sáu phần dữ liệu tạo sáu Map; ba máy nhận mỗi máy hai tác vụ kế tiếp.

Lưu ý: phần đầu vào là đơn vị chia việc; khối HDFS là đơn vị lưu trữ.

Vai trò của HDFS trong MapReduce

Đọc thêm

Hệ thống tệp phân tán Hadoop (HDFS) cung cấp lớp lưu trữ cho đầu vào và kết quả.

HDFS cung cấp vị trí bản sao để giao Map gần dữ liệu, đầu vào để đọc lại và nơi lưu kết quả Reduce.

HDFS quản lý dữ liệu. Hệ thống MapReduce phân chia, lập lịch và chạy lại tác vụ.

Giao tác vụ Map gần dữ liệu

Đọc thêm

Ưu tiên máy có bản sao; nếu không phù hợp, xét máy cùng rack rồi xa hơn.

A và D có bản sao B1; Map tại đó đọc cục bộ. B đọc từ A trong cùng rack; C đọc từ A qua hai rack.

A và D đều đọc được B₁ tại máy; bản sao không làm tăng số bản ghi đầu vào.

Chia đầu ra Map theo hàm phân phối

Đọc thêm

Hai văn bản, hai Map, hai Reduce; tạm bỏ Combine để thấy từng cặp.

M1 chia hai cặp mèo vào phần R0 và chó vào R1; M2 chia chim vào R0 và chó vào R1.

Mỗi Map lưu các phần trung gian trên đĩa cục bộ.

Chuyển dữ liệu trung gian (Shuffle)

Đọc thêm

Việc chuyển các phần trung gian tới tác vụ Reduce đã chỉ định gọi là Shuffle.

Mỗi Reduce lấy đúng phần của mình từ cả hai Map; R0 nhận mèo mèo chim, R1 nhận chó chó.

R₀ nhận nhiều khóa; mọi cặp cùng khóa vẫn về cùng một Reduce.

Nhóm theo khóa và đọc lần lượt

Đọc thêm

Hệ thống sắp xếp và ghép dữ liệu; hàm Reduce xử lý từng nhóm khóa.

R0 nhóm chim và mèo; Reduce cộng lần lượt hai giá trị của mèo để được 2.

Với đếm từ, Reduce chỉ cần một biến tổng cho khóa đang xử lý.

Lưu ý: nhóm đầy đủ về mặt logic không đòi giữ cả nhóm trong bộ nhớ.

Theo dõi trạng thái tác vụ

Đọc thêm

Tiến trình điều phối (Master) theo dõi mỗi tác vụ và máy thực thi nó.

Chờ, đang chạy, hoàn tất; tác vụ đang chạy bị lỗi trở về chờ để giao lại.

Máy thực thi báo tiến độ và kết quả; máy rảnh có thể nhận tác vụ tiếp theo.

Nơi lưu dữ liệu và cách phục hồi

Đọc thêm
Dữ liệuNơi lưuKhi mất máy lưu
Đầu vàoHDFS có bản saoĐọc bản sao khác
Đầu ra Map trung gianĐĩa cục bộChạy lại Map để tạo lại
Đầu ra Reduce đã hoàn tấtHDFSGiữ kết quả đã công bố

Giả thiết: hệ tệp dùng bản sao; còn ít nhất một bản sao HDFS truy cập được.

Phục hồi khi máy chạy Map hỏng

Đọc thêm

M₁ đã xong trên máy A, nhưng Reduce chưa lấy phần dữ liệu cần từ A.

Máy A hỏng; máy B đọc bản sao đầu vào, chạy lại M1 và cung cấp địa chỉ mới cho Reduce đang đợi.

Tiến trình điều phối đưa M₁ về chờ, giao máy khác chạy lại và báo vị trí đầu ra mới.

Lưu ý: Map đã xong vẫn phải làm lại nếu đầu ra cục bộ không còn truy cập được.

Phục hồi khi máy chạy Reduce hỏng

Đọc thêm

R₀ chưa hoàn tất; R₁ đã công bố kết quả O₁ lên HDFS.

R0 bỏ đầu ra tạm, chạy lại từ dữ liệu Map còn truy cập được; O1 đã hoàn tất được giữ.

R₀ mới lấy lại các phần trung gian và tính Reduce lại; chưa cần chạy lại các Map.

Nhiều lần thực thi của một tác vụ

Đọc thêm
Tình huốngCách xử lý
Lỗi hoặc mất liên lạcGiao lại tác vụ trên máy khác
Một tác vụ chạy quá chậmCó thể chạy thêm một bản dự phòng

Kết luận: mỗi tác vụ chỉ một kết quả được chấp nhận.

Giả thiết: hàm xác định, đầu vào không đổi.

Phạm vi chống chịu lỗi

Đọc thêm
Sự cốKhả năng phục hồi
Một máy thực thi hỏngLàm lại tác vụ hoặc đầu ra trung gian bị mất
Một rack không truy cập đượcDùng bản sao ở rack khác và giao lại tác vụ
Tiến trình điều phối hỏng (mô hình MMDS)Công việc phải được khởi động lại

Giả thiết: đầu vào còn đọc được và có máy thay thế.

Câu hỏi về phục hồi khi máy hỏng

Đọc thêm

Câu hỏi: trên ví dụ hai Map, hai Reduce.

  1. R₀ và R₁ lần lượt lấy phần nào từ M₁ và M₂?
  2. M₁ xong trên A; A hỏng trước khi R₀ lấy dữ liệu. Phần nào phải tính lại?
  3. R₁ đã công bố O₁ rồi máy chạy R₁ hỏng; HDFS còn bản sao O₁. Có cần chạy lại R₁?

6.Thực hành Hadoop với Docker Compose

Muốn chạy đếm từ trên cụm thật, phải dựng cụm Hadoop, viết Map, Reduce bằng Python và đối chiếu kết quả.

Docker Compose · HDFS · Hadoop Streaming · Bộ đếm

Mục đích và chuẩn bị thực hành

Thực hành
Mục đíchChạy bài đếm từ trên cụm Hadoop 6 container, một máy.
Kết quả mong đợichim 1 · chó 2 · mèo 2, khớp phép tính tay.
Chuẩn bịCài Docker trước lớp; mạch 5 là Đọc thêm, không tiên quyết.

Bộ mã: Hướng dẫn thực hành · Tải mã Docker Compose.

Cụm Hadoop trên một máy

Thực hành
NameNode lưu vị trí khối cho 2 DataNode; ResourceManager cấp tài nguyên cho 2 NodeManager chạy MapReduce; 6 container trên một mạng bridge.

NameNode lưu vị trí khối; 2 DataNode lưu khối và bản sao.
ResourceManager cấp tài nguyên; 2 NodeManager chạy MapReduce.

Khởi động bằng Docker Compose

Thực hành

Cài Docker Engine/Desktop và Compose plugin trước; giải nén bộ mã rồi vào thư mục lab.

cd hadoop-compose
docker compose pull
docker compose up -d
docker compose ps

pull tải image apache/hadoop:3.4.2-lean từ Docker Hub;
up -d tạo 6 container nền; ps liệt kê trạng thái.

Kiểm tra cụm đã sẵn sàng

Thực hành
docker compose exec namenode hdfs dfsadmin -report
docker compose exec namenode yarn node -list

Dấu hiệu sẵn sàng: 2 DataNode ở trạng thái Live,
2 NodeManager ở trạng thái RUNNING.

Giao diện web của HDFS ở 127.0.0.1:19870, của YARN ở 127.0.0.1:18088.

Hai văn bản trên HDFS

Thực hành
d1.txtmèo chó mèo
d2.txtchó chim

Trong cấu hình mẫu: hai tệp → hai Map. Hai bản sao không làm tăng số từ.

Script run-job.sh tự đưa data/*.txt lên HDFS bằng hdfs dfs -put.

Hàm Map bằng Python

Thực hành
import sys

# Mỗi từ phân cách bởi khoảng trắng đóng góp một lần xuất hiện.
for line in sys.stdin:
    for word in line.split():
        print(f"{word}\t1")

Đọc từng dòng từ stdin; với mỗi từ in word TAB 1 ra stdout.

Tệp đầy đủ là mapper.py trong bộ thực hành.

Giao diện giữa Python và Hadoop

Thực hành
stdin dòng văn bản vào mapper; stdout các cặp word TAB count; Hadoop phân phối và sắp xếp; reducer nhận các dòng cùng khóa liền nhau qua stdin.

Mapper in mèo TAB 1, mèo TAB 1…; Hadoop gom các dòng cùng khóa liền nhau rồi đưa vào reducer.

Hàm Reduce và Combine bằng Python

Thực hành
import sys
from itertools import groupby

# Hadoop đưa các dòng cùng khóa liền nhau; đọc nhóm lần lượt.
pairs = (line.rstrip("\n").split("\t", 1) for line in sys.stdin)
for word, group in groupby(pairs, key=lambda pair: pair[0]):
    total = sum(int(value) for _, value in group)
    print(f"{word}\t{total}")

Cộng giá trị trong nhóm; đầu vào và đầu ra cùng dạng word TAB count.

Tệp đầy đủ là reducer.py trong bộ thực hành.

Nộp công việc MapReduce

Thực hành
docker compose exec -T namenode bash /work/run-job.sh

Bốn dòng khai báo trong script (cùng một lệnh hadoop jar):
-files /work/mapper.py,/work/reducer.py · -mapper 'python3 mapper.py'
-combiner 'python3 reducer.py' · -reducer 'python3 reducer.py'

Tệp run-job.sh tạo thư mục đầu vào, đưa tệp lên HDFS và chọn thư mục đầu ra mới.

Đối chiếu kết quả

Thực hành
chim	1
chó	2
mèo	2

Script in đường dẫn đầu ra; ghép các tệp output/part-* thu được đủ ba cặp kết quả.

Trạng thái công việc trên YARN là SUCCEEDED (127.0.0.1:18088).

Quan sát các bộ đếm

Thực hành
5 cặp Map output, 4 cặp sau Combine, 3 cặp Reduce output; nhãn counter ghi số bản ghi.

Lần chạy kiểm thử: 5 cặp ra từ Map, 4 cặp sau Combine, 3 cặp ra từ Reduce.

Câu hỏi về lần chạy trên Hadoop

Thực hành

Câu hỏi: giải thích kết quả và cách kiểm chứng.

1Xóa khai báo Combiner trong script: kết quả đếm có đổi không?
2Với replication 2, vì sao tổng số từ đếm được vẫn là 5 chứ không phải 10?
3Bằng chứng nào cho thấy công việc đã chạy trên YARN và cho kết quả đúng?

7.Tổng kết và bài tập vận dụng

Muốn dùng MapReduce cho bài toán khác, phải chọn khóa và thông tin giữ lại theo đầu ra cần tính.

Kết quả và giả thiết · Thuật toán và chi phí · Câu hỏi tự kiểm tra · MMDS Bài 2.3.1

Kết quả và giả thiết không được bỏ

Kết quảGiả thiết không được bỏCông thức hoặc thuật toán
Một công việc MapReducehàm xác định, dừng; Reduce không phụ thuộc thứ tựMap, nhóm \(L_k\), Reduce
Combinegộp kết hợp, giao hoán; trạng thái đủ, như \((s,c)\)dạng khóa–giá trị như Reduce; chia chỉ ở Reduce
Chi phí đầu vàokhông tính đầu ra cuối\(C=I+H\)
Thời gian công việcpha nối tiếp; pha chờ máy chậm nhất\({T_P=\sum T_{\text{pha}}}\), \({T_{\text{pha}}=\max_m t_m}\)
Truyền, tăng tốcbăng thông ổn định; cùng phạm vi đo\({T\approx\lambda+V/B}\); \({S_P=T_1/T_P}\)

Thuật toán, bảo đảm và chi phí

Thuật toánĐầu vàoBảo đảmChi phí trên ví dụ
Đếm từ (khóa: từ)\(n\) văn bảnmỗi từ một cặp \((w,c(w))\)5 cặp × 16 byte = 80 byte; Combine: 4 cặp, 64 byte
Nhân ma trận–véc tơ (khóa: hàng \(i\))bản ghi \((i,j,a_{ij})\); \(v\) vừa bộ nhớ\(y=Av\)16 cặp Map, 8 sau Combine
Đếm từ phân biệt (khóa: từ, rồi \(g\))\(n\) văn bảnkết quả \(D\)5 cặp, 4 sau Combine; rồi 3 cặp
Trung bình (trạng thái \((s,c)\))\(a_1,\ldots,a_n\), \(n\geq1\)\(\mu=\sum s/\sum c\) (tổng chia số lượng)3 cặp Map, 2 sau Combine
Cộng \(n\) số trên \(P\) máy\(n\ge P\)đúng tổng\(W_P=n-1\); 16 số: \(6\tau\) so với \(15\tau\)

Câu trả lời cho vấn đề trung tâm

  • Map, nhóm theo khóa, Reduce cho chim 1, chó 2, mèo 2; Reduce cộng nên không phụ thuộc thứ tự.
  • Giá trị giữ đủ thông tin: \(y=(9,8,9,11)^T\), \(D=3\), \(\mu=5\); trung bình trực tiếp cho 6.
  • Ví dụ giả định bốn pha: \(T_4=10\) s, gồm điều phối 1 s, truyền và nhóm 3 s; \(S_4=2{,}4<4\); Combine: 80 còn 64 byte.
  • Hadoop: 5 cặp Map, 4 cặp sau Combine, 3 cặp Reduce, khớp chạy tay.

Kết luận: chọn khóa theo đầu ra, giữ đủ thông tin để gộp; truyền là chi phí phải đo.

Câu hỏi tự kiểm tra

Câu hỏi: trả lời và nêu kết quả đã dùng.

  1. Phân biệt việc của Map, Reduce và hệ thống trong đếm từ.
  2. Nêu điều kiện để Combine giữ nguyên kết quả; cho phản ví dụ.
  3. Tăng số máy có luôn giảm thời gian chạy?
  4. Nêu bằng chứng từ bài thực hành rằng công việc chạy đúng.

Nguồn và tài liệu đọc

Nguồn: Leskovec, Rajaraman, Ullman (2020), Mining of Massive Datasets, ấn bản 3, Chương 2, §§2.1–2.3, §2.5, tr.21–56.

Sách và trang chiếu của các tác giả: http://www.mmds.org.

Nguồn: Dean, Ghemawat (2004), MapReduce, OSDI, §§2–3; Manning, Raghavan, Schütze (2008), Introduction to Information Retrieval, §6.3.

Nguồn: Cornell CS5220 (2020); Apache Hadoop 3.4.2: HDFS Architecture, MapReduce Tutorial, Hadoop Streaming.

Bài 03 dùng phép nhân ma trận–véc tơ của bài này cho phép lặp PageRank.

Bài tập vận dụng

Nhu cầu: áp quy tắc chọn khóa và giá trị cho ba bài của MMDS, Bài 2.3.1.

Mỗi bài nộp đặc tả Map, Combine, Reduce và lập luận tính đúng.

  • (a) Số nguyên lớn nhất trong một tệp rất lớn.
  • (b) Trung bình cộng của mọi số nguyên trong tệp.
  • (d) Số giá trị phân biệt trong tệp.

Bài tập: số nguyên lớn nhất

Tệp rất lớn chứa các số nguyên; không cần khóa ở đầu ra.

Đầu ra là số nguyên lớn nhất trong toàn bộ tệp.

Câu hỏi: thiết kế thuật toán MapReduce.

Nộp đặc tả Map, Combine, Reduce và lập luận tính đúng.

Nguồn: MMDS, Bài 2.3.1(a), tr.40.

Bài tập: trung bình cộng của tệp số nguyên

Tệp rất lớn chứa các số nguyên; không cần khóa ở đầu ra.

Đầu ra là trung bình cộng của mọi số trong tệp.

Câu hỏi: thiết kế thuật toán MapReduce.

Nộp đặc tả Map, Combine, Reduce và lập luận tính đúng.

Nguồn: MMDS, Bài 2.3.1(b), tr.40.

Bài tập: số giá trị phân biệt

Tệp rất lớn chứa các số nguyên; không cần khóa ở đầu ra.

Đầu ra là số giá trị phân biệt trong tệp.

Câu hỏi: thiết kế thuật toán MapReduce.

Nộp đặc tả Map, Combine, Reduce và lập luận tính đúng.

Nguồn: MMDS, Bài 2.3.1(d), tr.40.