Nguyen Le Phong

Sự Phức Tạp Là Tất Yếu, Sự Đơn Giản Là Bền Vững: Bài Học Từ Hệ Thống Lớn — Và Cuộc Sống

Những năm đầu sự nghiệp, mình tin một hệ thống “xịn” phải là nơi hội tụ công nghệ mới nhất, nhiều lớp abstraction và càng nhiều “magic code” càng đẳng cấp. Nhiều năm với large-scale distributed systems đã dạy mình điều ngược lại. Sự phức tạp là cái giá tất yếu của tăng trưởng — nhưng sự đơn giản, thứ đến từ sự tường minh, mới là cái giúp một hệ thống (và một cuộc đời) sống sót qua việc người rời đi, công nghệ lỗi thời và yêu cầu dịch chuyển. Một góc nhìn ấm áp, gần gũi văn phòng về essential vs. accidental complexity, lãi kép của technical debt, vì sao giữ đơn giản lại khó hơn, và vì sao cùng ý tưởng đó giúp ta vững vàng giữa cuộc sống hiện đại.

Sự phức tạp là cái giá tất yếu phải trả cho tăng trưởng. Sự đơn giản là khoản đầu tư lặng lẽ cho tương lai. Một thứ giúp bạn lớn lên; thứ còn lại giúp bạn tồn tại sau khi đã lớn.

Trong những năm tháng đầu tiên của sự nghiệp kỹ sư, mình từng có một niềm tin gần như tuyệt đối: một hệ thống “xịn” phải là nơi hội tụ những công nghệ mới nhất, sở hữu những lớp abstraction tầng tầng lớp lớp, và càng nhiều “magic code” thì càng chứng tỏ đẳng cấp của người tạo ra nó.

Nhưng rồi nhiều năm lăn lộn với những large-scale distributed systems đã dạy cho mình một bài học rất khác.

Ở quy mô hàng chục triệu người dùng, mỗi dòng code không bao giờ chỉ dừng lại ở chuyện “đúng hay sai”. Nó còn là chi phí vận hành, là độ trễ, là trải nghiệm người dùng và sau cùng là hiệu quả kinh doanh. Sau vô số lần refactor, đập đi xây lại, và cả những đêm thức trắng tìm giải pháp cho những vấn đề do chính mình tạo ra, một nghịch lý cứ hiện ra mãi:

Sự phức tạp là tất yếu khi mọi thứ lớn lên. Nhưng sự đơn giản mới là nền tảng cho sự phát triển bền vững.

Đây là một góc nhìn ấm áp, cỡ-văn-phòng về nghịch lý ấy — vì sao phức tạp luôn tìm đến, cái bẫy âm thầm bào mòn hệ thống từ bên trong, “đơn giản” thật ra nghĩa là gì, vì sao giữ được sự đơn giản lại là lựa chọn khó hơn, và vì sao chính tư duy đó cũng giúp ta vững vàng giữa một cuộc sống hiện đại đầy biến số.

1. Tại sao sự phức tạp là tất yếu?

Mọi hệ thống vĩ đại đều bắt đầu từ những thứ nhỏ bé: một vài API, một database, và một team nhỏ ngồi chung một bàn. Nhưng quy luật của sự phát triển không cho phép ta đứng yên.

Khi traffic tăng lên nhiều lần, khi business đòi hỏi tốc độ (time-to-market), và khi các ràng buộc về SLA hay Security & Privacy trở nên nghiêm ngặt, hệ thống buộc phải tiến hóa. Lúc này, sự phức tạp không mời mà đến. Và nó xuất hiện dưới rất nhiều hình hài.

Nơi nó lớn lênTrong hệ thốngLiên tưởng đời thường
Hạ tầngSharding, Replication, Multi-level Caching, Multi-regionMột ổ đĩa chung thành nhiều văn phòng, kèm backup, chi nhánh và các bản sao phải luôn đồng bộ
Kiến trúcEvent-driven, Async processing, Distributed transactionsMột danh sách việc cần làm thành nhiều team bàn giao qua lại nhau qua các múi giờ
Bảo mật & Tuân thủData Encryption, RBAC/ACL, Audit Logging, ràng buộc pháp lýMột chiếc chìa khóa văn phòng thành thẻ từ, log ra vào, NDA và kiểm toán hằng năm
Quy trìnhBackward compatibility, Zero-downtime migration, CI/CD AutomationSửa lại cửa hàng trong khi vẫn mở bán, không một lần đuổi khách ra về

Và đây là phần ta hay quên: phức tạp còn đến từ chính con người và tổ chức. Team A cần tốc độ; Team B cần an toàn. Ops cần ổn định; Product cần tính năng. Những xung đột lợi ích đó biến một kiến trúc phần mềm thành tấm bản đồ chằng chịt các thỏa hiệp — phần mà không sơ đồ nào vẽ ra cả.

Vì vậy, phức tạp không phải là một sai lầm. Nó là hệ quả tự nhiên của việc giải quyết những bài toán ngày càng khó hơn. Đây chính là Essential Complexity — sự phức tạp cốt yếu, nằm sẵn trong bản thân bài toán và không thể cắt bỏ.

Một cách nghĩ hữu ích

Bạn không thể “xóa” essential complexity, cũng như không thể ước cho một thành phố đang lớn lên hết cần đèn giao thông. Mục tiêu không phải là một hệ thống không có chút phức tạp nào — mà là một hệ thống mà mọi sự phức tạp đều xứng đáng, mỗi mảnh đều có lý do bạn nói thành lời được.

2. Cái bẫy của “sự phức tạp không kiểm soát”

Nếu phức tạp là tất yếu, vậy tại sao các hệ thống vẫn có lúc phải lên bàn mổ để “đập đi xây lại”? Câu trả lời nằm ở người anh em song sinh độc hại của nó: Accidental Complexity — sự phức tạp ta vô tình thêm vào, thứ mà bài toán chưa bao giờ yêu cầu.

Hệ thống hiếm khi sụp đổ vì nó lớn. Nó sụp đổ khi:

  • Những giải pháp tạm thời, “đủ xài cho lúc này” ngủ quên rồi lặng lẽ thức dậy thành kiến trúc chính thức.
  • Các lớp abstraction không còn che giấu sự phức tạp mà trở thành chính sự phức tạp — một khoản thuế bạn phải trả cho mỗi lần thay đổi.
  • Nỗ lực để ra một tính năng trở nên bất cân xứng: code vài dòng, nhưng tốn hàng giờ chỉ để hiểu chúng nằm ở đâu.
  • Mã nguồn dính chặt vào nhau đến mức một thay đổi nhỏ cũng kích hoạt hiệu ứng cánh bướm, gây lỗi dây chuyền.
Một tính năng đáng lẽ chỉ tốn phần phức tạp cốt yếu, nhưng trong một hệ thống bị bỏ bê nó thực sự tốn phần cốt yếu cộng thêm một lớp phức tạp ngẫu nhiên dày phía trên. Lớp dư thừa đó chính là phần mà kỷ luật có thể trả lại cho bạn. HAI LOẠI PHỨC TẠP Cốt yếu bản thân bài toán Chi phí đáng lẽ phải trả Cốt yếu vẫn như cũ Ngẫu nhiên mớ rối tự gây ra Chi phí thực sự phải trả phần kỷ luật trả lại cho bạn
Essential complexity là cái sàn bạn không thể đi thấp hơn. Accidental complexity là mọi thứ chất chồng phía trên — và chính đống đó là nơi sự đơn giản phát huy giá trị.

Khi đống ấy đủ cao, hệ thống rơi vào trạng thái trì trệ. Nó trở thành một hộp đen đáng sợ: khó hiểu, khó debug, khó mở rộng, khó onboarding người mới, và — dấu hiệu rõ nhất — ai cũng sợ thay đổi nó.

Đây là lúc Technical Debt không còn cư xử như “nợ” nữa, mà bắt đầu cư xử như lãi kép. Mỗi đường tắt bạn chưa trả lại âm thầm tính phí thêm một lần, và tổng số vượt qua Cognitive Load của đội ngũ — lượng hệ thống mà một con người có thể thực sự giữ trong đầu cùng một lúc.

Cái bẫy “tạm thời”

Không gì bền vững bằng một giải pháp tạm thời mà… chạy được. Tờ giấy nhớ bạn dán hôm thứ Hai một năm sau vẫn còn trên màn hình, và giờ đã có ba thứ khác phụ thuộc vào nó. Accidental complexity gần như không bao giờ đến dưới dạng một quyết định sai lớn — nó tích tụ từng đường tắt “hợp lý” một.

3. Sự đơn giản: Chìa khóa để tồn tại

Khi nói về sự đơn giản, điều đầu tiên cần làm rõ là nó không phải cái gì: đơn giản không phải là sơ sài (simple is not crude). Đơn giản không phải “ít code” hay “ít công nghệ”. Trong kiến trúc hệ thống, đơn giản thể hiện qua một thứ trên hết — Sự tường minh (Clarity).

Một hệ thống khiến bạn sợMột hệ thống bạn hiểu được
Luồng nghiệp vụ phức tạp chỉ nằm trong đầu một anh seniorLuồng phức tạp được diễn giải bằng các mô hình đủ rõ để nhiều người cùng hiểu
Hành vi phụ thuộc các giả định ngầm và “phải biết thì mới biết”Hành vi mang tính dự đoán được, được ghi lại, không phải truyền miệng
Khi sự cố xảy ra, không ai biết nên bắt đầu nhìn từ đâuKhi sự cố xảy ra, có thể khoanh vùng và biết nên quan sát thành phần nào trước
Mỗi kỹ sư giải cùng một việc theo một kiểu cá nhân riêngCó cách làm chuẩn cho những việc thường gặp, mặc định là vậy
Một thay đổi nhỏ lan ra khắp cả hệ thốngCó thể thay đổi từng phần mà không gây hiệu ứng dây chuyền
Không ai chắc Database, Application hay “đâu đó” mới là nơi giữ một quy tắcRanh giới trách nhiệm rõ ràng: việc của Database thì Database lo, việc của Application thì Application làm

Sự tường minh giúp giữ hệ thống đủ đơn giản để phát triển một cách tự tin và đáng tin cậy. Và theo thời gian, nó còn làm một việc giá trị hơn nữa: giảm đáng kể cognitive load trong quá trình vận hành và bảo trì.

Khi hệ thống lớn lên, sự đơn giản có kỷ luật giữ độ phức tạp ở dưới giới hạn cognitive load của đội ngũ và vẫn dễ hiểu, trong khi sự phức tạp không kiểm soát vượt qua giới hạn đó và trở thành một hộp đen không thể bảo trì. phức tạp thời gian / tăng trưởng → giới hạn cognitive load của đội ngũ đơn giản & kỷ luật → vẫn hiểu được phức tạp mất kiểm soát ↗ vượt vạch → trì trệ
Hai hệ thống có thể cùng quy mô. Cái mà độ phức tạp còn nằm dưới vạch giới hạn con người giữ nổi trong đầu mới là cái tồn tại được.

Đó mới là phần thưởng thật sự. Khi hệ thống tường minh, người mới — và cả “người cũ” đã xây nó nhưng từ lâu đã quên hết chi tiết — đều có thể nhìn lại và hiểu được vì sao nó được thiết kế như vậy, để rồi tiếp tục duy trì và tiến hóa nó lên. Thay vì chỉ học một cách lo lắng cách “làm cho nó chạy”.

Sợi chỉ xuyên suốt

Chỉ khi con người thật sự làm chủ được hệ thống, hệ thống mới có cơ hội để tồn tại. Con người mới là nền tảng mà mọi thứ lâu dài được xây trên đó — không phải framework, không phải cloud, không phải lớp abstraction khôn ngoan nhất.

4. Sự đơn giản là một lựa chọn đầy thử thách

Làm cho mọi thứ phức tạp thì rất dễ: thêm một layer, thêm một công nghệ là xong. Giữ cho mọi thứ đơn giản thì khó vô cùng. Nó đòi hỏi kỷ luật và sự sẵn lòng cân nhắc trade-offs không ngừng:

Khi bạn bị cám dỗ muốn…Con đường hấp dẫnCon đường đơn giản, có kỷ luật
Làm sẵn cho một nhu cầu có thể sẽ tới“Làm cho thật linh hoạt ngay bây giờ, phòng khi cần”YAGNI — làm khi nhu cầu là thật, không phải tưởng tượng
Với tay tới một công cụ mới bóng bẩyDùng công nghệ hype mà ai cũng đang khoe trên mạngChọn công nghệ “nhàm chán” nhưng đã được kiểm chứng, mà 3 giờ sáng vẫn vận hành bình tĩnh được
Biến mọi thứ thành configurableVô số nút bấm và tùy chọn “cho linh hoạt”Một default tốt; chỉ thêm một nút khi có ca thực tế đòi hỏi

Nói gọn, chọn sự đơn giản nghĩa là dám nói “Không” với những tính năng chưa cần tới, dám hy sinh một chút flexibility giả tạo để đổi lấy sự ổn định thật, và dám chọn giải pháp nhàm-chán-mà-hiệu-quả thay vì công nghệ hào-nhoáng-mà-rủi-ro.

Thành thật mà nói? Đạt đến sự đơn giản chưa bao giờ là dễ — kể cả với mình. Không phải giải pháp nào mình đưa ra cũng đạt tới dạng tinh gọn lý tưởng ngay từ lần đầu. Kẹt giữa những giới hạn khắc nghiệt của tài nguyên và thời gian, con đường đi tới sự đơn giản luôn đầy rẫy khúc quanh. Nhưng đây là cách mình làm hòa với điều đó: sự đơn giản không phải một đích đến cuối cùng — nó là kim chỉ nam. Nó là thứ khiến mình luôn quay lại refactor hệ thống sau mỗi bài học mới.

Thử trong buổi review tới

Trước khi thêm một layer, một tùy chọn hay một dependency, hãy hỏi to một câu: “Cái này giải quyết vấn đề thật, đang hiện hữu nào — và nó khiến người tiếp theo phải hiểu nó tốn bao nhiêu?” Nếu bạn không trả lời rõ được nửa đầu, rất có thể bạn vừa bắt gặp một mảnh accidental complexity trước khi nó kịp ra đời.

Bởi vì trong vòng đời của bất kỳ hệ thống nào, công nghệ sẽ lỗi thời, nhân sự sẽ rời đi, quản lý sẽ thay đổi, và yêu cầu kinh doanh sẽ dịch chuyển. Thứ duy nhất ở lại là những quyết định kiến trúc — và “hệ quả” của chúng.

5. Từ hệ thống đến cuộc sống

Càng làm lâu, mình càng nhận ra cách tư duy này không chỉ đúng trong công việc. Nó đúng với cả cuộc sống của chính mình.

Cuộc sống hiện đại vốn dĩ cũng giống một hệ thống phân tán: quá nhiều thông tin, quá nhiều mối quan hệ, quá nhiều áp lực, quá nhiều biến số. Sự phức tạp đó là tất yếu — ta không tránh được. Và nếu cứ để mình bị cuốn theo, cố “scale” bản thân để xử lý mọi thứ cùng lúc mà không có kiểm soát, ta sẽ sớm rơi vào quá tải và kiệt sức.

Vì thế, có những lúc nước đi khôn ngoan là dừng lại một nhịp để suy nghĩ kỹ hơn — hay chấp nhận bắt đầu lại, để những bước sau vững hơn và đi được xa hơn.

“Sự đơn giản là bền vững” với mình không chỉ là một nguyên tắc làm việc. Đó là một triết lý sống mà mình vẫn đang tập theo đuổi.

Và xin nói rõ, đơn giản ở đây không phải chối bỏ hay trốn chạy một thế giới phức tạp. Đơn giản là năng lực kiểm soát sự phức tạp:

  • Biết gạt bỏ những nhiễu động để tập trung vào những gì cốt lõi nhất.
  • Biết từ chối những “thỏa mãn” ngắn hạn vốn âm thầm lấy đi giá trị dài hạn của bạn.
  • Chỉ khi giữ được sự đơn giản, ta mới duy trì được sự tỉnh táo và sức bền để đi qua những giai đoạn phức tạp nhất của một đời người — và từ đó, tìm thấy một hạnh phúc bền vững.

Những điều đọng lại

  • Phức tạp là cái giá của tăng trưởng. Khi traffic, đội ngũ và ràng buộc lớn lên, hạ tầng, kiến trúc, bảo mật và quy trình đều khó hơn. Đó là phức tạp cốt yếu — không phải thất bại, mà là sức nặng xứng đáng.
  • Kẻ giết người là accidental complexity. Hệ thống hiếm khi chết vì lớn; nó chết vì những đường tắt “tạm thời” thành vĩnh viễn, những abstraction hết tác dụng, và mã nguồn rối đến mức một thay đổi làm hỏng năm thứ.
  • Technical Debt biến thành lãi kép. Một khi độ phức tạp vượt giới hạn cognitive load của đội ngũ, hệ thống trở thành hộp đen mà ai cũng sợ động vào.
  • Đơn giản không phải sơ sài — đơn giản là sự tường minh. Hành vi dự đoán được, ranh giới rõ ràng, cách làm chuẩn hóa, và thay đổi giữ được tính cục bộ.
  • Giữ đơn giản là lựa chọn khó hơn. Nó cần kỷ luật: YAGNI, công nghệ nhàm-chán-nhưng-đã-kiểm-chứng, một default tốt — và can đảm nói “không”.
  • Con người mới là nền tảng thật sự. Công nghệ lỗi thời, người rời đi, yêu cầu dịch chuyển; thứ ở lại là quyết định kiến trúc và hệ quả của chúng. Một hệ thống mà con người làm chủ được là một hệ thống có cơ hội tồn tại.
  • Cùng một bài học giúp cuộc sống vững vàng. Bạn không tránh được sự phức tạp của đời sống, nhưng bạn kiểm soát được nó — gạt nhiễu động, từ chối những cái lợi ngắn hạn rẻ tiền, và giữ đủ tỉnh táo để đi đường dài.

Bạn không được chọn việc phức tạp có đến hay không — trong hệ thống của bạn hay trong những ngày của bạn. Nó luôn đến. Nhưng bạn được chọn sẽ làm gì với nó: để nó chất chồng không ai soi xét, hay nhẹ nhàng refactor về một thứ đủ tường minh để trao lại. Phức tạp là cái bạn trả để lớn lên. Đơn giản là cái bạn đầu tư, để thứ bạn dựng nên — và cả con người bạn — vẫn còn đứng vững rất lâu sau khi cơn hype đã đi qua.

Bạn thấy bài viết thế nào?

Câu hỏi thường gặp

Essential complexity và accidental complexity khác nhau ở đâu?
Essential complexity nằm sẵn trong bản thân bài toán — phần khó không thể cắt bỏ mà bạn gánh lấy ngay khi phục vụ hàng chục triệu người dùng, tôn trọng các SLA nghiêm ngặt, hay đáp ứng những yêu cầu bảo mật và tuân thủ thật sự. Bạn không thể xóa nó, cũng như một thành phố đang lớn không thể xóa nhu cầu đèn giao thông. Còn accidental complexity là sức nặng dư thừa bạn vô tình thêm vào: một đường tắt “tạm thời” đã thành kiến trúc, một abstraction không còn che giấu gì nữa, mã nguồn rối đến mức một thay đổi làm hỏng năm thứ. Mục tiêu lành mạnh không phải là phức tạp bằng không — mà là bảo đảm mọi phức tạp bạn gánh đều cốt yếu và xứng đáng, không có đống ngẫu nhiên chất thêm phía trên. Sự đơn giản, hiểu rất sát nghĩa, chính là công việc kéo lớp ngẫu nhiên đó nhỏ lại.
“Giữ đơn giản” có nghĩa là né công nghệ mới hay làm ít tính năng đi không?
Không — và đây là cách hiểu sai phổ biến nhất. Đơn giản không phải sơ sài, và nó không có nghĩa là ít code hay ít công nghệ. Trong kiến trúc, đơn giản nghĩa là tường minh: hành vi dự đoán được, ranh giới chỉ ra được, có cách làm chuẩn cho việc thường gặp, và thay đổi giữ tính cục bộ thay vì lan khắp nơi. Bạn hoàn toàn có thể dùng một công nghệ mới mạnh mẽ mà vẫn đơn giản, miễn là nó xứng đáng có mặt và một kỹ sư bình thường vẫn suy luận được về nó. Thứ mà sự đơn giản chối bỏ là phức tạp không ai nói được lý do — flexibility “phòng khi cần”, các tùy chọn không ai dùng, và magic code chỉ tác giả mới hiểu.
Làm sao biết hệ thống của tôi đang quá nhiều accidental complexity hay technical debt?
Hãy quan sát khoảng cách giữa công sức và kết quả, và quan sát nỗi sợ của mọi người. Các dấu hiệu cảnh báo: code vài dòng nhưng mất hàng giờ chỉ để tìm đúng chỗ đặt; một thay đổi nhỏ kích hoạt một loạt lỗi không liên quan; chỉ một người hiểu một luồng quan trọng; onboarding kỹ sư mới mất thời gian đau đớn; và — tín hiệu lớn nhất — cả team âm thầm sợ động vào vài khu vực nhất định. Khi hệ thống đã lớn vượt quá thứ một con người giữ nổi trong đầu (giới hạn cognitive load), technical debt đã đi từ “nợ” sang lãi kép. Chính nỗi sợ-thay-đổi đó là tín hiệu để bắt đầu refactor về phía tường minh, thay vì tiếp tục chất chồng.
Chọn “công nghệ nhàm chán” có phải chỉ là sợ đổi mới không?
Hoàn toàn không. Chọn công nghệ nhàm chán, đã được kiểm chứng là đặt cược vào sự ổn định và vào những con người phải vận hành hệ thống — gồm cả bạn, lúc 3 giờ sáng khi có sự cố. Công nghệ chạy theo hype đôi khi thật sự tốt hơn, nhưng nó cũng kèm chi phí ẩn: tooling chưa chín, tài liệu mỏng, ít người debug được, và những bất ngờ trong production. Nước đi có kỷ luật không phải là từ chối mọi công nghệ mới; mà là bắt công nghệ mới phải chứng minh rủi ro của nó xứng đáng với một nhu cầu rõ ràng, đang hiện hữu — thay vì chọn nó chỉ vì nó đang là xu hướng. Một sự đổi mới mà bạn vận hành bình tĩnh được và trao lại được cho người sau đáng giá hơn nhiều so với cái mới mà bạn sợ động vào.
Bài học về hệ thống này áp dụng vào cuộc sống đời thường, phi kỹ thuật, như thế nào?
Cuộc sống hiện đại hành xử rất giống một hệ thống phân tán: quá nhiều thông tin, quá nhiều mối quan hệ, quá nhiều áp lực, quá nhiều biến số. Sự phức tạp đó là tất yếu, và việc cố “scale” bản thân để gánh tất cả cùng lúc mà không kiểm soát sẽ dẫn thẳng tới quá tải và kiệt sức. Cùng một nguyên tắc sẽ giúp ích: gạt nhiễu động để tập trung vào điều cốt lõi nhất, từ chối những thỏa mãn ngắn hạn vốn âm thầm lấy đi giá trị dài hạn, và đừng ngại dừng lại hay thậm chí bắt đầu lại để những bước sau vững vàng hơn. Đơn giản trong cuộc sống không phải trốn chạy một thế giới phức tạp — nó là năng lực kiểm soát sự phức tạp, và chính sự kiểm soát đó cho bạn sự tỉnh táo và sức bền để tìm thấy một hạnh phúc bền vững.