Hôm nay cuối tuần ở nhà rảnh rỗi không có gì làm nên lại ngứa tay viết một bài để chia sẻ lại hệ thống nhận diện user spam comment có thể phục vụ hàng triệu người dùng mà không có điểm chết 
Sau bài viết này tôi hi vọng có thể giúp các bạn thiết kế ra một hệ thống mà với hệ thống đó các bạn có thể tự tin tuyên bố rằng Hệ thống của tôi là trường tồn với thời gian, sống cùng trời đất bất chấp số lượng user, CCU có nhiều đến đâu :))
Nào bắt đầu thôi !!!
Lets Go GIF by Diddy


Việc đầu tiên khi thiết kế một hệ thống hay bắt đầu của một dự án là chúng ta cần làm rõ đề bài là gì, khách hàng cần gì. Đấy nhắc đến những thứ này tôi lại có cảm xúc dạt dào khi đi làm một BA bất đắc dĩ. Làm sao để giải thích cho người không hiểu về kỹ thuật để họ hiểu về kỹ thuật, làm sao để khai thác những thứ cần thiết từ khách hàng để thiết kế hệ thống cho đúng trong khi họ không biết được họ muốn những gì. Nói chung là nhiều lúc chỉ muốn đấm nhau :)))
Mà thôi lại lan man, quay lại chủ đề chính. Chúng ta cần lấy đề bài và yêu cầu.
#Đề bài: Hãy thiết kế hệ thống nhận diện người dùng spam có khả năng nhận diện 14 triệu comment một ngày và có khoảng 1 triệu người dùng trong 1 ngày
#Yêu cầu: Nhận diện được user spam càng sớm càng tốt và tỉ lệ sai sót thấp.
Meme Reaction GIF
Đấy anh em ạ. Nhiều khi họ chỉ cho mình như thế yêu cầu thôi chứ cũng không có gì thêm cứ nghĩ mọi thứ dễ lắm ấy. Dễ thì ông tự làm đi. Nghĩ trong bụng thế thôi chứ nói ra thì lấy gì mà ăn :-<


Không sao tôi là super man lại thêm nhiệt tình nên tôi sẽ làm cho bạn thoả mãn :))

Noice Thats Nice GIF

Khi đã có đầy đủ yêu cầu việc tiếp theo chúng ta cần làm là xác định các thành phần chính cần có trong hệ thống.

#Xác định các thành phần của hệ thống
Nhận diện spam comment dựa trên nội dung để có thể phát hiện realtime, ngăn chặn sớm các tin lừa đảo, mua bán dâm,…Nhận diện spam comment dựa trên hành vi: để có thể phát hiện ra các trường hợp mà nhận diện dựa trên nội dung không phát hiện ra. Bởi vì nội dung có thể có nhiều cách thay đổi để lách luật nhưng hành vi thì hầu như là không thay đổi.Hệ thống hybrid để tận dụng điểm mạnh của 2 phần trên và để khắc phục ưu nhược điểm của nhau từ đó để có kết quả tốt nhất.CMS: để cảnh báo cho các admin quản trị hệ thống
Xác định được các thành phần chính rồi giờ thì chúng ta sẽ làm gì để xử lý được dữ liệu lớn trong thời gian realtime đây.
Và đây là cách


Với mô hình trên các khối sẽ giao tiếp với nhau qua Queue. Vì sao tôi lại lựa chọn dùng queue thay vì gọi API như mô hình truyền thống ? Câu trả lời là vì để xử lý một lượng dữ liệu lớn trong khoảng thời gian ngắn thì chúng ta cần chia nhỏ dữ liệu ra và xử lý phân tán và song song trên nhiều server trong cùng 1 lúc. Tức là nếu ta xử lý 1 request hết 10s thì nếu ra phân tán và xử lý song song 1000 request cùng 1 lúc thì 1000 request cũng chỉ hết 10s mà mà thôi.
#Cách thức hoạt động của hệ thống
Cụ thể, với mô hình này luồng làm việc sẽ như sau:
Bước 1: Khi người dùng comment sẽ được chuyển lên queue. Từ đây, sẽ có n số lượng consumer trên m của khối Comment Consumer tiếp nhận comment và nhận diện dựa trên nội dung bằng AI và bằng luật có sẵn (khối Rule based xử lý).
Bước 2: Sau khi comment của người dùng được nhận diện dựa trên nội dung xong thì sẽ được ghi vào file local lưu vào HDFS, kết quả nhận diện và user id của người dùng sẽ gửi lại queue và được các consumer của khối Behavior based nhận diện dựa trên hành vi từ trong log lịch sử được ghi vào HDFS (Khối File local storage).
Bước 3: Kết quả nhận diện hành vi và nhận diện dựa trên nội dung sẽ được chuyển đến khối Hybrid để tận dụng ưu điểm của cả 2 khối hành vi và nội dung. Cuối cùng kết quả sẽ được gửi về queue để cho các phần mềm bên thứ 3 nhận kết quả và hiển thị cảnh báo lên CMS.
Các khối hỗ trợ nhưng không thể thiếu là Monitor và Central Log.
#Monitor
Tôi thường thấy phần này các bạn nhất là các bạn mới vào nghề hay quên đi phần monitor. Đối với hệ thống nhỏ thì có thể các bạn ít khi phải quan tâm đến sự sống chết, lỗi phát sinh có hay không. Nhưng đối với các hệ thống lớn nhất là hệ thống phân tán thì việc quản lý tiến trình nào đang chạy, tiến trình nào bị chết, trong quá trình chạy có exception không rất là quan trọng để đảm bảo cho service luôn luôn trong trạng thái active hoặc có sự cố thì khắc phục kịp thời.
Trong phần này thì các bạn nên cảnh báo tất cả các vấn đền đến điện thoại của các bạn thông qua các api free như api của telegram hoặc các api nội bộ miễn là các cảnh báo đó luôn hiển thị đến mắt bạn khi cần thiết.
Ngoài việc check service của bạn sống hay chết thì việc cảnh báo các exception và traceback phát sinh bất kỳ cũng nên được đặt vào monitor. Vì trong quá trình dev thì việc để lọt case hay bạn không lường trước được exception là điều bình thường nên hãy luôn đặt try catch và trong catch sẽ get traceback và gửi đoạn traceback đó về điện thoại của bạn.
Đối với hệ thống này của tôi có một luật rất chặt chẽ và cũng rất nguy hiểm đó là với những user spam sẽ bị khoá tài khoản trong khi đó, việc AI nhận diện nhầm là việc không thể tránh khỏi nên một ngày đẹp trời khi bạn deploy mô hình mới hay admin thêm một luật mới và làm cho toàn bộ user trong hệ thống bị khoá tài khoản. Để tránh cái ngày đẹp trời đó thì trong hệ thống Monitor tôi làm ra một cơ chế mà tôi gọi là cơ chế Áp-tô-mát. Đó là khi số lượng user được phát hiện là spam tăng bất thường, đột biến so với các ngày thì sẽ không tự động khoá tài khoản người dùng nữa mà chuyển sang cơ chế chỉ cảnh báo trên CMS và thông báo đến toàn bộ đến những người có “chức trách” để nhận định rằng hệ thống có phát sinh lỗi không. Nếu không lỗi gì thì sẽ cho tắt Áp-tô-mát để tiếp tục tự động khoá tài khoản sau khi phát hiện được người dùng spam.
À một phần quan trọng nữa là bạn nên gửi hostname và ip của server kèm theo log để còn biết node nào trong cụm bị lỗi nhé 

#Central Log
Vì đây là hệ thống phân tán nên thông tin 1 request của bạn sẽ được ngẫu nhiên 1 server nào đó trong hệ thống phân tán của bạn xử lý (Nói là ngẫu nhiên thôi chứ thực tế là thằng server nào khoẻ hơn, nhanh hơn thì tỉ lệ cao rơi vào thằng đó). Như vậy phát sinh ra một vấn đề khi bạn cần check log thì bạn phải vào tất cả server đó để check. 1,2 server thì ok chứ 100 server thì ssh vào được hết chắc mất cả ngày rồi nói gì đến việc check rồi fix lỗi. Như vậy, vấn đề cần đẩy log về một nơi tập trung là việc cần thiết.
#Ưu và nhược điểm
“Cái gì cũng có 2 mặt của nó và khó khăn không bao giờ là hết chỉ là chuyển từ trạng thái này sang trạng thái khác” và hệ thống này cũng vậy.
Ưu điểm:
Xử lý song song và phân tán, dữ liệu được lưu trữ trên tất cả các server nên nó luôn hoạt động dựa trên mô hình active – active. Tức là dù có 1 server chết thì cũng không ảnh hưởng đến hệ thống. Hệ thống chỉ chết khi tất cả server cùng chết.Tận dụng cơ chết FIFO của Queue nên server nào mạnh, xử lý nhanh thì sẽ get được nhiều message từ queue về xử lý nhiều hơn các server yếu hơn. Vì vậy, vấn đề quản lý tài nguyên cho cụm phân tán được giải quyết phần nào. Còn nếu muốn control kỹ hơn về tài nguyên và phân loại tài nguyên thì bạn nên nghiên cứu thử YARN.Dễ dàng scale: vì là mô hình phân tán active – active nên bạn chỉ cần thêm server hoặc ổ cứng miễn là server cứ có ram, có cpu và có điện là join và cụm phân tán là chạy được đồng nghĩ với việc tiết kiệm chi phí.
Nhược điểm:
#Túm cái váy lại
Điểm mấu chốt của hệ thống này là việc bạn dùng queue làm thứ trung gian để giao tiếp giữa các khối hay các service và việc chia nhỏ các khối hay chia 1 service to thành service nhỏ, điều luồng một cách tài tình từ đồng bộ thành bất đồng bộ và ngược lại để tận dụng tối đa khả năng xử lý song song.
Hãy luôn nhớ câu chuyện bó đũa Cái gì to thì mình cứ chia nhỏ nó ra.
Một hệ thống không chỉ có thiết kế phần mềm mà việc thiết kế hạ tầng vật lý và công nghệ sử dụng cũng hết sức quan trọng nhưng bài viết dài quá rồi nên tôi sẽ nói tiếp trong một bài viết khác.
1s quảng cáo :3