- Không nhất thiết phải có hạ tầng riêng phức tạp để triển khai Durable Execution; cốt lõi là lưu giữ an toàn trạng thái của workflow
- SQLite cung cấp trạng thái bền vững dựa trên giao dịch mà không cần dịch vụ cơ sở dữ liệu riêng, đồng thời giữ an toàn trạng thái tiến hành của workflow mà không cần network hop hay control plane bổ sung
- Khi dùng Litestream để stream bất đồng bộ các thay đổi của SQLite tới kho lưu trữ đối tượng tương thích S3, có thể giữ trạng thái gần với runtime nhưng vẫn sao chép được cho mục đích sao lưu, migration và kiểm tra
- Với các workflow bùng nổ theo đợt và mang tính thử nghiệm như AI agent, mô hình micro VM hoặc container nơi mỗi agent có một đơn vị trạng thái SQLite nhỏ, độc lập sẽ đơn giản hơn, rẻ hơn và có lợi hơn về cô lập lỗi so với một hệ thống chia sẻ lớn duy nhất
- Nếu cần tính sẵn sàng cao hoặc khả năng mở rộng chia sẻ trên diện rộng thì Postgres phù hợp hơn, nhưng nhiều hệ thống workflow ban đầu chưa cần tới mức hạ tầng đó
Cốt lõi của thực thi bền vững
- Thực thi bền vững thường được bàn đến như thể cần hạ tầng bền vững, nhưng điều thực sự quan trọng là trạng thái workflow (workflow state); còn compute có thể rẻ và mang tính dùng một lần
- Trong Obelisk, trạng thái tiến hành của workflow được lưu trong execution log, được replay từ lịch sử đã được lưu bền vững, và activity có thể được retry
Vì sao SQLite phù hợp
- SQLite cung cấp trạng thái bền vững dựa trên giao dịch mà không cần thêm dịch vụ cơ sở dữ liệu riêng
- Có thể giữ an toàn trạng thái tiến hành của workflow mà không cần network hop, control plane bổ sung hay gánh nặng vận hành mới
- Trong nhiều hệ thống, một file cơ sở dữ liệu cục bộ chính là mức hạ tầng phù hợp nhất
Đảm bảo tính di động với Litestream
- Litestream stream bất đồng bộ các thay đổi của SQLite tới kho lưu trữ đối tượng tương thích S3, nhờ đó giữ trạng thái gần với runtime đồng thời hỗ trợ sao chép để sao lưu, migration và kiểm tra
- Lưu ý: việc sao chép của Litestream là bất đồng bộ, nên nếu volume SQLite biến mất trước khi các bản ghi cục bộ mới nhất chưa được sao chép kịp, chúng có thể bị thiếu khi khôi phục
- Đây có thể là mức chấp nhận được với nhiều workflow AI và workflow thử nghiệm, nhưng là một mô hình khác với cơ sở dữ liệu chia sẻ có tính sẵn sàng cao
- Mô hình vận hành thực tế: chạy máy chủ Obelisk cùng cơ sở dữ liệu SQLite, sao lưu bằng Litestream, và khi cần thì observer kéo cơ sở dữ liệu về — có thể tái sử dụng cùng một file để replay cục bộ, debug và phân tích hành vi agent
Vì sao đặc biệt có lợi cho AI agent
- AI agent và workflow do AI tạo ra có đặc tính bùng nổ theo đợt và mang tính thử nghiệm, nên việc có đơn vị trạng thái nhỏ, tự hoàn chỉnh cho từng agent hoặc tenant sẽ thuận lợi hơn cho việc suy luận
- Với một fleet máy chủ nhỏ dựa trên micro VM hoặc container, cấu hình vận hành cơ sở dữ liệu SQLite độc lập cho từng máy cùng bản sao lưu trên object storage sẽ đơn giản hơn, rẻ hơn và tốt hơn về cô lập lỗi so với một hệ thống chia sẻ lớn luôn bật
Khi nào nên dùng Postgres
- Obelisk cũng hỗ trợ Postgres, và đó là lựa chọn phù hợp khi cần tính sẵn sàng cao, khả năng mở rộng chia sẻ trên diện rộng, hoặc đặc tính triển khai mà cơ sở dữ liệu mạng phù hợp hơn
- Postgres cũng phù hợp hơn nếu sao chép bất đồng bộ sang object storage không phải là mô hình độ bền mong muốn
- Nhiều hệ thống workflow ở giai đoạn đầu không cần bắt đầu với mức hạ tầng vượt quá nhu cầu thực tế của trạng thái
- Chỉ với tổ hợp SQLite cục bộ + sao lưu Litestream S3 + worker chi phí thấp cũng có thể tạo nên một hệ thống bền vững với hạ tầng tối thiểu, và đây có thể là giá trị mặc định hợp lý nhất trong môi trường AI agent
1 bình luận
Ý kiến trên Hacker News
Tôi bắt đầu dùng Temporal để xây dựng workflow; với ứng dụng cục bộ thì nó triển khai khá gọn nhẹ, và trong các cài đặt cục bộ được cô lập thì dùng SQLite
Việc xử lý retry API, dọn dẹp workflow và tác vụ trở nên thực sự đơn giản, nên tôi khuyên nên thử một lần. Về mặt triết lý, nó đi đúng cùng hướng với điều bài viết này đề xuất, nhưng bổ sung một giao diện rất phong phú và linh hoạt, phù hợp để agent sử dụng. Cũng rất dễ xem workflow qua web UI và rà soát các lần chạy của agent
Temporal gần như thêm độ tin cậy cao hơn cho hệ thống với chi phí gần như miễn phí. Hệ thống phân tán và đáng tin cậy rất khó, nên tôi nghĩ tốt hơn là đừng phát minh lại bánh xe
Nếu bạn muốn dễ dàng nhìn vào cơ sở dữ liệu SQLite, hiểu điều gì đang diễn ra trong workflow, kết hợp các tác vụ riêng lẻ và giúp workflow có thể được gọi một cách đơn giản, thì Temporal đáng để xem qua
Cùng với đó, tôi gần như đã giảm hẳn việc dùng file cho agent. Markdown và JSON cũng tốt, nhưng khi làm ứng dụng cục bộ nhỏ thì chúng giống như một cái bẫy. LLM xử lý SQLite rất tốt, và từ đó có thể render ra bất kỳ định dạng nào bạn muốn như Markdown hay JSON. Nếu agent có thể truy vấn đúng các hàng cần thiết thay vì chạy jq hay grep trên Markdown, thì cũng tiết kiệm được rất nhiều token. Bạn sẽ có một hệ thống quản lý dữ liệu tự chứa, tính di động tốt, đồng thời buộc cấu trúc dữ liệu phải quy củ hơn so với việc dùng nhiều file. Khi dự án cục bộ nhỏ phát triển lớn hơn hoặc trở nên chính thức hơn, bạn cũng có thể chuyển tiếp sang MySQL/Postgres, và khi đó đã sẵn có schema cùng tính kỷ luật dữ liệu
Temporal trở nên phức tạp hơn nhiều khi mở rộng quy mô. Việc vận hành Cassandra chẳng vui vẻ gì, còn Ringpop và TChannel thì rất khó debug khi có sự cố. Hỗ trợ SQL backend không cho phép replica scale ngang vì yêu cầu nhất quán, nên chỉ khả thi với một instance duy nhất
Tùy cách viết code, việc sửa mã đã nằm trong workflow cũng trở nên phức tạp. Những thay đổi làm đảo thứ tự sự kiện trong history sẽ phá vỡ tính quyết định của các worker đã được triển khai
Chúng tôi dùng Temporal rất nhiều; ai bắt đầu bằng scripting hay automation đơn giản thì đều thích, còn ai xây hệ thống production thực sự trên đó thì đều ghét. Có thể là do chúng tôi chưa đủ giỏi về vận hành, nhưng bức tranh màu hồng trong các bình luận ở đây không khớp với trải nghiệm của tôi
Tôi chưa tự làm, nhưng muốn nghe thêm trải nghiệm thực tế
Tôi không hiểu sự ám ảnh với việc dùng SQLite cho ứng dụng production thực tế. SQLite là cơ sở dữ liệu nhúng nên hoàn toàn không phù hợp để quản lý đồng thời
Đó là lý do tồn tại của các máy chủ cơ sở dữ liệu như Postgres hay MySQL. Toàn bộ vai trò của chúng là cho phép nhiều tiến trình sửa đổi dữ liệu đồng thời từ các máy khác nhau
Đây là nguyên lý cơ bản của khoa học máy tính, nên phe hô hào “SQLite cho mọi thứ” có vẻ hơi thiếu kinh nghiệm
SQLite là một cơ sở dữ liệu production rất tốt cho nhiều workload thực tế, và điều này đã được tài liệu hóa rộng rãi. Nó rất khác Postgres, nên cần học một bộ kỹ thuật hoàn toàn khác
Một góc nhìn là SQLite có thể rất phù hợp với những phần của hệ thống vốn được phân vùng mạnh một cách tự nhiên
net/httpcủa Go, nhiều dịch vụ đã có thể xử lý toàn bộ mức tải mà người ta có thể hình dung. Điều này càng đúng hơn nếu theo thời gian bạn có thể nâng cấp phần cứng, và SQLite có thể mở rộng khá dễ dàng tới hàng trăm nghìn TPSThứ thực sự phải đánh đổi là tính sẵn sàng cao/chuyển đổi dự phòng và khôi phục thảm họa, nhưng ngay cả việc đó cũng có giải pháp. Các hệ thống một máy chủ nhìn chung bền vững đến ngạc nhiên. Bởi khi không có control plane phức tạp, độ sẵn sàng của hệ thống thường giảm khi quy mô tăng lên
Tôi thích đánh giá lại các “best practice” hiện có dưới góc nhìn của thay đổi công nghệ. Đặc biệt là khi nó hướng tới sự đơn giản hơn. Vận hành một trang mạng xã hội gia đình bằng một DB SQLite trên một VPS là rất tuyệt. Có khoảng 15 người dùng và hầu như không cần bảo trì. Tôi cũng chạy một instance FreshRSS và trang “now” bằng SQLite
Ở chỗ làm, trong vài chục năm qua tôi đã dùng SQLite cho đủ loại mục đích. Tôi đã dùng nó cho hàng đợi công việc tạm thời, để nạp và truy vấn nhanh rất nhiều log cục bộ, và để hiển thị/lọc theo thời gian thực bằng https://github.com/simonw/datasette tuyệt vời của simonw
Tôi nghĩ nó gần với “SQLite ở nhiều nơi hơn bạn tưởng rất nhiều” hơn là “SQLite cho mọi thứ”
Công việc về edge SQLite của kentonv/Cloudflare có thể đã phổ biến hóa thêm suy nghĩ này, nhưng đó vốn đã là một xu hướng sẵn có. https://blog.cloudflare.com/sqlite-in-durable-objects/
Muốn biết và tận dụng những trường hợp nhỏ nhưng hữu ích như vậy không phải là dấu hiệu thiếu kinh nghiệm, mà ngược lại có thể là dấu hiệu của kinh nghiệm
SQLite có khả năng được dùng nhiều hơn tất cả các engine cơ sở dữ liệu khác cộng lại. Có hàng tỷ bản sao SQLite tồn tại ngoài thực tế. Nó có mặt trong thiết bị Android, iPhone và thiết bị iOS, Mac, các bản cài đặt Windows 10/11, Firefox/Chrome/Safari, Skype, iTunes, Dropbox client, TurboTax và QuickBooks, PHP và Python, hầu hết TV và set-top box, phần lớn hệ thống giải trí trên xe hơi, cùng vô số ứng dụng khác
https://sqlite.org/mostdeployed.html
Cách này khiến khả năng mở rộng dễ hiểu hơn rất nhiều. Chỉ cần tách ra rồi lặp lại. Cứ mỗi N người dùng thì thêm một shard
Đổi lại, bạn sẽ có các vấn đề khác như truy vấn xuyên shard, ví dụ phân tích dữ liệu, và cách cân bằng tải khi người dùng rời đi hoặc trở nên cũ kỹ
Nhưng bạn có thể tránh được toàn bộ vấn đề mở rộng chỉ mục dùng chung do insert/update tạo ra ở quy mô người dùng lớn
Nó trở thành một cơ sở dữ liệu phân cấp hơn là một cơ sở dữ liệu quan hệ
Đã thay thế tất cả những thứ sau bằng Go + SQLite: Intercom, Zendesk, email marketing, Kanban, Todo, payment stack, issue tracker, forum, giám sát uptime, bản sao PagerDuty
Vì đang bán hàng chục sản phẩm, tôi nghĩ sao không tự làm hết luôn
Tất cả đều chạy trên cùng một server và dùng rất ít bộ nhớ. Tôi đã thay toàn bộ các công cụ SaaS đang dùng bằng những thứ này
Sau khi chuyển sang server riêng, chi phí giảm còn khoảng 1/10 so với số tiền từng trả cho các giải pháp cloud managed, trong khi vẫn giữ cùng mức độ sẵn sàng cao và còn có độ trễ thấp hơn. Một phần lý do cũng là tail latency từng tăng do noisy neighbor trên VPS
Trước đây tôi đã tốn rất nhiều tiền cho mấy thứ này, nhưng giờ đã vận hành được 4 tháng và chỉ cần vài cập nhật nhỏ
Triển khai thật sự rất đơn giản. Không có Docker hay Kubernetes, chỉ có các service systemd và các binary được build trên máy phát triển rồi deploy
Trước đây tôi cũng trả tiền cho các dịch vụ như MaxMind hay IPData, nhưng rồi tự làm dịch vụ định vị địa lý IP và trong thử nghiệm nó cho hiệu năng tốt hơn phần lớn các giải pháp hiện có
Ban đầu là để thay Uptime Robot, sau đó tự tin hơn nên thay luôn PagerDuty. Sau nữa là thay Intercom
Cuối cùng, tôi luôn nghe câu “đừng tự xây payment stack”, nhưng nghĩ YOLO nên quyết định tự mình phạm sai lầm đó. Tôi đã nghiên cứu các giải pháp thanh toán hiện có, tự phát triển và triển khai nó, và đến giờ hoàn toàn chưa có vấn đề gì
Phía trước tôi dùng Caddy
Tôi nhận ra rằng trong số các chức năng mà đa số sản phẩm SaaS cung cấp, thực ra tôi chỉ dùng 1~5%, còn những chức năng thật sự cần thì ngày càng bị chôn sâu hơn trong các nền tảng “enterprise-grade” này, khiến workflow khó khăn hơn
Tôi sẽ không cho xem các sản phẩm thương mại vì đối tác và khách hàng chắc sẽ không thích biết tôi rẻ đến mức nào, nhưng tôi gọi đây là sự tháo vát
Có thể cho xem app miễn phí. Mới ra mắt gần đây và đã có hơn 20 nghìn người dùng: https://macrocodex.app/
App này chỉ dùng bản sao Zendesk. Email được xử lý bằng Cloudflare routing nên chi phí vận hành gần như bằng không
Giữa một file và cơ sở dữ liệu đa phân vùng là cả một khoảng cách lớn. Khi vận hành thực tế phụ thuộc vào nó, chạy cơ sở dữ liệu trong container không hợp gu của tôi
Cá nhân tôi thấy nhiều ETL có thể xử lý cục bộ mà không cần kéo cơ sở dữ liệu enterprise vào. Trong những trường hợp đó, DuckDB tốt hơn SQLite khoảng 5~10 lần, đồng thời đơn giản và nhanh hơn rất nhiều so với việc dựng một cơ sở dữ liệu Postgres chuyên dụng
Với scripting thông thường, một script awk 20 dòng không thể so với một script SQL tương đương dựa trên DuckDB sạch sẽ hơn nhiều, chắc chắn hơn và dễ bảo trì hơn
Mong là MotherDuck không rơi vào tình cảnh phải pump-and-dump để IPO. Sẽ rất buồn nếu mất công cụ này vì lòng tham doanh nghiệp quen thuộc
Câu chuyện về script awk 20 dòng rất thú vị. Hôm qua tôi gần như đã đưa ra đúng lập luận đó tại Ubuntu Summit. Từ một thời điểm nào đó, việc viết shell script bằng GNU coreutils trở nên thiếu thực tế, còn script SQL của DuckDB mở rộng tốt hơn về độ phức tạp, khả năng bảo trì và thường cả hiệu năng nữa. Slide ở đây: https://blobs.duckdb.org/slides/duckdb-ubuntu-summit-2026.pd... trang 32~36
Ngoài ra MotherDuck phát triển một DBaaS mã nguồn đóng trên nền DuckDB. Họ xây trên DuckDB, và kết nối tới MotherDuck bằng DuckDB, nhưng là một công ty được đầu tư VC riêng biệt có trụ sở tại Seattle
DuckDB được phát triển bởi DuckLabs, một công ty bootstrap tại Amsterdam, tức công ty dựa trên doanh thu. Tài sản trí tuệ của dự án thuộc về tổ chức thứ ba là DuckDB Foundation, một tổ chức phi lợi nhuận tại Hà Lan. Xem thêm tại https://duckdb.org/faq#how-are-duckdb-the-duckdb-foundation-...
Tôi đã tạo một thư viện cho phép cập nhật đồng thời an toàn SQLite DB trên S3[0]
Nó hoạt động khá hiệu quả và an toàn nhờ dùng SQLite sessions extension ít người biết đến cùng compare-and-swap của S3 cho một file metadata nhỏ. Tôi đang dùng nó rất vui trong nhiều dự án nhỏ cần DB lưu trạng thái cho hàm Lambda nhưng không muốn trả chi phí cho cả một instance cơ sở dữ liệu
[0]: https://github.com/psanford/s3db
SQLite cho hiệu năng đáng ngạc nhiên ngay cả khi so với Postgres trong ứng dụng một node
Postgres dùng bộ nhớ nhiều hơn rất nhiều, và I/O phải đi qua giao tiếp liên tiến trình. Trong khi đó, với SQLite bạn có thể giữ mọi thứ trong cùng tiến trình thông qua shared connection pool
Tôi đang thử nhiều storage engine cho agent harness, và với SQLite thì trên một vCPU đơn lẻ có thể đạt tới 7,5 nghìn phiên đồng thời, còn Postgres thì hoặc crash hoặc cạn kết nối
[0] https://github.com/impalasys/talon/pull/23#issuecomment-4577...
Ngay khoảnh khắc bạn rời khỏi thread hiện tại thì đã là một cuộc chơi thua về độ trễ. Nếu không ép giao tiếp liên thread, SQLite có thể hoạt động ở thang thời gian micro giây
Trong bối cảnh một node, Postgres là quá mức cần thiết. Không nên kỳ vọng nó cạnh tranh với SQLite
Nó gần giống như benchmark giữa HashMap gần như chạy trong bộ nhớ với Redis, rồi ngạc nhiên khi HashMap cho kết quả tốt trong điều kiện lý tưởng nhất
Sau nhiều năm đọc về SQLite, tôi đã thử dùng nó cho một dự án cá nhân, nhưng sau khi quen với Postgres thì tôi bị sốc vì hệ thống kiểu dữ liệu của nó quá nghèo nàn.
Thật sự rất kém, tôi không hiểu vì sao nó lại được ca ngợi nhiều đến vậy.
https://sqlite.org/datatype3.html
https://www.postgresql.org/docs/current/datatype.html
Cảm giác xử lý ngày/giờ như đang dùng một cơ sở dữ liệu 30 năm tuổi, và khi chèn dữ liệu thì chẳng có gì được ép buộc cả. Cần ai đó giải thích vì sao nhiều người lại thích nó đến vậy.
PRAGMA journal_mode = WAL
PRAGMA foreign_keys = ON
Something non-null
PRAGMA busy_timeout = 1000This is fine for most applications, but see the manual
PRAGMA synchronous = NORMALIf you use it as a file format
PRAGMA trusted_schema = OFFTùy binding mà có thể cần thêm các tùy chọn khác. Ví dụ, ứng dụng Python không nên dùng giá trị mặc định của mô-đun sqlite3. Mặc định đó đơn giản là sai. Trước 3.12 thì thậm chí không có lựa chọn nào khác ngoài việc dùng binding ngoài thư viện chuẩn: https://docs.python.org/3/library/sqlite3.html#transaction-c...
Cũng nên dùng strict table. https://www.sqlite.org/stricttables.html
Dù hơi khó dùng, bạn cũng có thể dùng ràng buộc CHECK. Ví dụ với hỗ trợ ngày tháng tích hợp của SQLite thì làm được, nhưng khá gượng gạo:
CHECK (
date(my_date_col) IS NOT NULL
AND my_date_col = date(my_date_col)
)
Cần
IS NOT NULLvìdatetrả về NULL khi ngày không hợp lệ. Kiểm tra còn lại là vì nó cũng chấp nhận cả ngày Julius, nêndate('2026')sẽ trở thành một thời điểm nào đó trong năm 4707 TCN.Tôi đồng ý là nó gây thất vọng, đặc biệt là trước khi có strict table.
Bạn nên xem DuckDB. Nó gần giống một SQLite có kiểu dữ liệu tử tế. Tuy nhiên, nó là OLAP, tức array-of-structs, chứ không phải OLTP, tức struct-of-arrays, nên với tải SQLite thông thường thì hiệu năng có thể tệ hơn. Nhưng với những ứng dụng thực sự cân nhắc giữa hai bên thì có lẽ khác biệt không lớn.
Tôi đã chuyển từ nhiều cụm Postgres lớn sang SQLite, và hiện toàn bộ một dịch vụ có số người dùng hoạt động hàng tháng 7 chữ số đang chạy trên SQLite durable objects.
Cần suy nghĩ khác về mẫu truy cập, nhưng lợi ích đem lại hoàn toàn xứng đáng.
Cách đặt vấn đề này rất hay. Nếu vấn đề chính là lưu trạng thái workflow một cách bền vững, có thể quan sát được và dễ khôi phục, thì trong nhiều trường hợp SQLite là đủ.
Tôi rất muốn sớm thấy vòng lặp tiếp theo của ý tưởng này: “workflow bền vững chỉ cần log là đủ”.
Một lý do khiến các giải pháp kiểu “chỉ cần log là đủ” có thể thất bại là khi log không đáng tin cậy trở thành một cuộc tấn công chèn đầu vào[1].
Hãy kiểm tra SBOM, và đừng quên bao gồm cả pipeline CI/CD[2].
[1] https://news.ycombinator.com/item?id=48315440
[2] https://github.com/jqwik-team/jqwik/issues/708#issuecomment-...
Nói nghiêm túc thì, làm chuyên gia là biết dùng đúng công cụ cho đúng việc.