Categories
Review sách

Review sách “Chủ nghĩa Khắc kỷ” của William B. Irvine

Lần đầu tiên đọc một cuốn sách về triết học mà cảm thấy hào hứng như cuốn này và quả thực sách đã để lại một ấn tượng cực kỳ sâu sắc đến cá nhân mình nên nay viết vài dòng review để mọi người có thêm chút thông tin về cuốn sách “Chủ nghĩa Khắc kỷ – Phong cách sống bản lĩnh và bình thản” của tác giả William B. Irvine.

Thấy bìa cuốn này vài tháng trước, lúc đó có lên wiki tìm hiểu xem chủ nghĩa Khắc kỷ là gì và cảm thấy nó như nói về con người mình, tính cách của mình nên cũng hào hứng chờ đón mua cuốn này. Và quả thật là khi cầm cuốn sách trên tay, đọc từ đầu đến cuối thì như mô tả tính cách của Tuấn đến hơn 90%.

Bản thân Tuấn và cũng như nhiều người (trong đó có cả gấu) nhận xét thì tính cách và lối sống của Tuấn có phần khác những người xung quanh, và điều này cũng dẫn đến không ít mâu thuẫn không cần thiết trong cuộc sống và công việc. Tuy nhiên, chả hiểu sao lối tính cách này nó vô tình ăn sâu và trở thành cách sống và làm việc của mình. Mãi cho đến khi đọc xong cuốn sách này thì mình thật ngạc nhiên là mình sống khá giống với những người theo chủ nghĩa Khắc kỷ …cách đây gần 2000 năm.

Chủ nghĩa Khắc kỷ có từ thời Hy Lạp (thế kỷ 3, trước công nguyên), bị “thất truyền” hơn cả ngàn năm và dạo gần đây mới được chú ý bởi tính chất và phong cách đặc trưng của chủ nghĩa sống này. Cuốn sách này trình bày lịch sử ra đời của chủ nghĩa Khắc kỷ, những cái tên nổi bật đại diện cho trường phái triết học này như Seneca, Epictecus và nhất là vị vua La Mã nổi tiếng Marcus Aurelius.

Ngoài việc giới thiệu về lịch sử ra đời, phần chính của sách là nói về những tính chất, hành động được coi là kim chỉ nam cho lối sống Khắc kỷ và những hướng dẫn thực hành lối sống này. Các chỉ dẫn cách ứng phó với những tình huống trong cuộc sống nếu muốn thực hành lối sống Khắc kỷ cũng được đề cập trong sách, bao gồm hướng dẫn đối phó với sự kiểm soát, vận mệnh, bổn phận với xã hội, đối phó với sự xúc phạm, cơn giận, đau buồn, tuổi già và cả cái chết.

Ngoài ra, sách cũng bàn về sự giàu sang, theo đuổi danh vọng, địa vị đối với người sống Khắc kỷ và các yếu tố kiềm chế bản thân trước các ham muốn, dục vọng để hướng đến lối sống thuận theo tự nhiên, chỉ ưu tiên tiếp nhận sự tích cực, vui vẻ và tránh xa, bỏ qua những điều tiêu cực, không lành mạnh.

Quả thật là khá ngạc nhiên khi thấy mình có lối sống khá gần với người theo trường phái Khắc kỷ khi đọc hết các mô tả tâm lý và hướng dẫn thực hành trường phái này. Ít ra có thể thấy mình cũng có một triết lý sống để đeo đuổi và giúp mình nhanh chóng ra các quyết định hằng ngày trong cuộc sống và công việc.

Tác giả cũng khuyến cáo không phải ai cũng có thể theo đuổi trường phái Khắc kỷ cũng như không có trường phái nào là tốt nhất, mỗi người, mỗi cá nhân sẽ tìm thấy cho mình một trường phái thích hợp để định hình lối sống của mình.

Mình có trích dẫn một số đoạn hay từ sách, hy vọng các bạn sẽ thấy được phần nào đặc trưng của trường phái Khắc kỷ.

Khi nói về Sự xúc phạm:

“Trong quá trình thực hành chủ nghĩa Khắc kỷ, dần dà chúng ta sẽ không còn quan tâm đến ý kiến của người khác về mình. Chúng ta sẽ không sống nhằm đạt được sự chấp thuận hay tránh né sự phản đối của họ, và bởi chúng ta không quan tâm đến ý kiến của họ, chúng ta sẽ không cảm thấy đau đớn khi bị họ xúc phạm. Kỳ thực, một nhà hiền triết theo phái Khắc kỷ có lẽ sẽ xem hành vi xúc phạm của những người xung quanh như tiếng chó sủa bên tai. Khi một con chó sủa, ta có thể nghĩ thầm rằng con chó kia dường như không ưa ta, nhưng sẽ thật ngu ngốc nếu ta để cho mình bực tức vì chuyện này và đắm chìm trong suy nghĩ, “Ôi, trời! Con chó kia không ưa mình!”

Bàn về cuộc sống xa hoa:

“Một người khắc kỷ sẽ làm gì nếu người ấy giàu có, mặc dù không chạy theo giàu sang? chủ nghĩa Khắc kỷ không yêu cầu người đó từ bỏ sự giàu sang; nó cho phép họ tận hưởng sự giàu sang và sử dụng của cải để mang lại lợi ích cho bản thân và những người xung quanh.”

“Khi chúng ta thấy mình đang khao khát một điều gì đấy, chúng ta nên dừng lại để tự hỏi liệu ham muốn của ta là thuận tự nhiên hay trái tự nhiên, và nếu nó có trái tự nhiên, ta nên nghĩ kỹ về việc thỏa mãn nó. Seneca cảnh báo, sự xa hoa dùng mưu kế để thúc đẩy những thói hư tật xấu: Trước tiên, nó khiến chúng ta muốn thứ không cần thiết, sau đó nó làm chúng ta muốn những thứ nguy hiểm cho ta. Chẳng mấy chốc, tâm trí trở thành nô lệ cho những ý thích nhất thời và khoái lạc của cơ thể.”

Trở thành người Khắc kỷ:

“Nhìn chung, có một triết lý sống, dù là triết lý Khắc kỷ hay những triết lý khác, có thể đơn giản hóa đáng kể cuộc sống hằng ngày. Nếu bạn đã có một triết lý sống thì việc đưa ra quyết định sẽ tương đối đơn giản: Khi cân nhắc giữa các tùy chọn mà cuộc sống mang đến, bạn đơn giản sẽ chọn một thứ (phù hợp nhất) có thể giúp bạn đạt được các mục tiêu đề ra bởi triết lý sống của bạn. Khi thiếu một triết lý sống thì ngay cả những lựa chọn tương đối đơn giản cũng có thể trở thành cuộc khủng hoảng ý nghĩa cuộc sống. Suy cho cùng bạn khó mà biết nên chọn cái gì khi thực sự không chắc chắn về điều mình muốn.”

Sau khi đọc sách này thì mình sẽ mạnh dạn hơn cho mảng sách về triết học và hy vọng khám phá nhiều hơn các trường phái khác. Hy vọng bài viết này sẽ giúp bạn hiểu hơn về chủ nghĩa Khắc kỷ và nhìn triết học như một môn khoa học thường thức và giúp cải thiện suy nghĩ và cuộc sống hằng ngày.

Categories
Miscellaneous

Bàn về mục đích đọc sách

Sáng nay khí trời mát mẻ, lại là dịp đầu tháng nên kiếm một đề tài nhẹ nhàng và gần gũi để viết trong thời gian chờ anh em đồng nghiệp vào làm. Mình định viết về đề tài sách cũng khá lâu nhưng chưa biết bắt đầu thế nào, chợt nhớ đến cách đây ít lâu có đọc một bài blog về việc nếu chúng ta ngưng sử dụng các mạng xã hội (facebook, twitter,..) thì có thể dành thời gian đó đọc khoảng 200 cuốn sách trong một năm. Wow!!!

Nếu đọc những bình luận của bài viết đó, cũng như bình luận từ những trang dẫn link (VD: Reddit, Hackernews..) thì thấy có nhiều luồng bình luận, đại khái là có 2 nhóm chính xoáy vào việc tác dụng của việc đọc sách là đọc nhiều cũng chả có tác dụng gì và một nhóm là đọc có tác dụng. Tất nhiên, mình ủng hộ nhóm đọc sách có tác dụng và đọc càng nhiều càng có tác dụng nhiều. Chẳng thế mà Warren Buffer đọc mỗi ngày 800 trang, Bill Gates mỗi năm đọc hơn 50 cuốn.

Như nhiều bạn cũng biết là Tuấn thích đọc sách và chia sẻ về sách. Để tránh các bạn trẻ (kể cả bạn già) bị ảnh hưởng bởi tư tưởng đọc sách không có tác dụng và đọc nhiều sách là vô ích nên Tuấn mới quyết định làm loạt bài “Bàn về sách” gồm 4 phần:

  • Bàn về mục đích của sách (bài viết bạn đang xem)
  • Bàn về mua sách
  • Bàn về đọc sách
  • Bàn về hậu đọc sách

Trong bài này, mình sẽ chia sẻ về mục đích của việc đọc sách và giúp các bạn không bị lạc lối trong đống sách. Như hầu hết chúng ta đã được “dạy dỗ”, mục đích đọc sách từ khi học lớp 1 đến tốt nghiệp đại học (hoặc cao học) là đọc sách giúp tăng khả năng thi đậu và lấy lòng bạn bè, thầy cô, giáo sư. Không thể phủ nhận là cho đến ngày nay, một vài kiến thức trong sách giáo khoa đang nằm trong tiềm thức của bạn đôi khi “hiện” về giúp bạn một số tình huống nào đó mà bạn ít ngờ được.

Khi mình dùng từ sách, các bạn có thể hiểu là mình đang đề cập đến những ấn phẩm để đọc, in thành nhiều trang và đóng thành tập như sách, truyện, manga, comic, tạp chí, sách tranh…

Nhìn chung, mình phân loại mục đích của việc đọc sách thành 3 mục đích chính:

  1. Đọc sách để giải trí
  2. Đọc sách để học hỏi
  3. Đọc sách để làm kinh tế

Đọc sách để giải trí

Đây là mục đích dễ dàng nhận thấy được khi các bạn đọc các sách văn học như truyện ngắn, tiểu thuyết…mục đích là giải trí nên đọc thể loại này không chú trọng vào kiến thức thu gặt được mà chú trọng vào cảm xúc, mô tả không gian được tác giả dựng lên, từ không gian kì ảo trong các truyện thần tiên, không gian bí ẩn trong các thể loại kinh dị, trinh thám hay không gian đời thường như các truyện ngôn tình hiện đại…

Chính vì mục đích giải trí nên nhiều nhà-đọc-sách-thượng-đẳng thường chỉ trích, chê bai các bạn thích đọc văn học, tiểu thuyết. Tuy nhiên, có thể họ chưa đọc thử hoặc không có thời gian để đọc thể loại sách này. Nếu đọc sách sẽ thấy những bộ phim chuyển thể từ sách ít khi nào hay bằng sách. Bởi đọc sách truyện mô tả, buộc bạn phải duy trì một khối lượng trí nhớ gần như là dài hạn cho toàn bộ nhân vật, kèm theo đó là lưu giữ được mạch truyện.

Bên cạnh đó, một kỹ năng mà mình đánh giá cao nhất là khả năng tưởng tượng không gian, bối cảnh cho các tình tiết trong sách. Mình có đọc một cuốn sách có đề cập đến một nghiên cứu cho thấy những người có khả năng hình dung, tưởng tượng được một hình học không gian thì có khả năng tư duy logic tốt hơn và khuyến khích trẻ em, thanh thiếu niên tiếp cận để phát triển khả năng tượng hình.

Ngoài ra, có nhiều sách là truyện ngắn, tiểu thuyết đọc thấy ly kì nhưng lại đem lại cho bạn nhiều kiến thức về vùng miền, lĩnh vực mà ngữ cảnh cuốn sách mang lại như những câu chuyện về du lịch, trinh thám công nghệ…

Do đó, đừng xem thường những cuốn sách viết ra với mục đích giải trí, đôi khi tác dụng nó mang lại thấm sâu hơn vào tiềm thức mà bạn không hề biết được.

Đọc sách để học hỏi

Đây là mục đích mà nhiều người-đọc-sáchngười-không-đọc-sách nghĩ tới thường xuyên cho việc đọc sách. Và cũng chính mục đích này dẫn đến không biết bao nhiêu tranh cãi về tác dụng của đọc nhiều sách. Nguyên nhân sâu xa của việc tranh cãi này nằm ở việc chúng ta đánh đồng và nhầm lẫn giữa việc đọc, hiểu và nhớ. Họ (những người chỉ trích) nói rằng đọc nhiều sách mà không nhớ, không hiểu gì hết thì thà khỏi đọc cho rồi vì đọc xong có nhớ gì đâu.

Bản thân hành động đọc sách là một hành động đơn thuần, dùng mắt, miệng để đưa câu chữ chạy qua não và hy vọng những con chữ này lưu lại ở não càng lâu càng tốt (gọi là nhớ) và biết được cách sử dụng, ý nghĩa của những câu chữ chạy qua (gọi là hiểu). Bạn có nhớ ngày xưa mình học thuộc lòng bảng cửu chương thế nào chứ và ngày nay vẫn dùng?

Nếu không nhớ, không hiểu thì coi như là không đọc là một quan điểm sai lầm của nhiều cán-bộ-lão-thành-bận-mưu-sinh, bởi vì ngoài việc lưu vào tiềm thức, nó sẽ thúc đẩy thay đổi hành động mỗi ngày. Không tin bạn có thể thử vào nhà sách tìm 10 cuốn sách về tình yêu mà đọc, đảm bảo bạn sẽ ngọt ngào hơn. Hoặc kiếm những thể loại truyện kinh dị, chém giết đẫm máu mà đọc, đảm bảo não bạn sẽ hoạt động hết công suất. Và kể cả nó cũng ảnh hưởng vào giấc mơ đấy, thử đi. Đây chính là tác dụng đọc sách ảnh hưởng tiềm thức.

Các bạn có thể nói lĩnh vực tiềm thức là một lĩnh vực bí ẩn, chưa khám phá kỹ nên mình lấy ví dụ khác cho việc đọc rồi quên mà đem lại tác dụng. Đây là lý do chính mà mình thích đọc nhiều sách, chính là vén bức màn ngu dốt. Có một nghịch lý kỳ lạ là con người càng ít đọc (ít học) thì lại càng thấy mình ít ngu dốt hơn những người đọc nhiều (học nhiều) !!!. Càng đọc càng thấy mình ngu dốt. Đấy chính là tư tưởng của hiệu ứng Dunning–Kruger mà mình có một bài viết cách đây 10 năm.

Việc đọc nhiều sách không phải chỉ để nhớ, học thuộc lòng, hiểu tường tận mà đôi khi đơn giản chỉ là đễ bớt ngu về một thứ gì đó, như là những địa danh ở Nhật hoặc những kiến thức trong ngành y học, vật lý học… mà nếu không đọc thì cả đời cũng không nghĩ là có những cái như vậy.

Một khi bức màn ngu muội của bạn được vén ra ngày một nhiều, mà mình hay nói là bức màn vô minh của mình ngày càng được vén ra thì mình nhìn mọi thứ với con mắt thông cảm và dễ hiểu hơn và lại thích đọc ngấu nghiến hơn nữa. Do đó, đừng nghe ai nói là đọc sách nhiều không có tác dụng, đó là lời khuyên từ những người không bao giờ đọc sách và cảm thấy ganh tỵ với những người có thời gian đọc sách và ngày càng bớt ngu muội.

Đọc để làm kinh tế

Đây là nhóm nhỏ, nhưng không kém phần quan trọng. Có một số ngành nghề kiếm tiền trực tiếp từ việc đọc sách. Nhưng nhóm đọc để làm kinh tế  mình nói đến là những người đọc sách rồi “thông báo” lên Facebook, Twitter…PR, lấy chút danh tiếng từ cộng đồng. Thực ra bạn đọc sách hay, khoe lên mạng để người khác biết là việc bình thường (mình cũng hay khoe lên Facebook kiếm vài xu nổi tiếng mà).

Mình vẫn luôn đánh giá cao những người khoe sách lên mạng xã hội bất kể bạn có đọc cuốn sách đó hay chưa. So với những người suốt ngày khoe điện thoại, quần áo, xe cộ, gái gú…thì khoe sách vẫn tốt hơn nhé. Hãy khoe khi còn có thể, ít ra bạn cũng đã mua sách, có công suy tư về sách và suy tư cho cộng đồng, giúp sách đi xa hơn đến mọi người.

Như vậy, thông qua bài này mình đã chia sẻ những góc nhìn cá nhân về việc đọc sách và đọc nhiều sách. Bản thân mình đặt mục tiêu năm nay sẽ đọc 100 cuốn nên sẽ cố gắng nhiều hơn trong việc cân bằng cuộc sống, công việc và…đọc sách. Nếu bài viết có phần đụng chạm đến những anh hùng không cần đọc sách vẫn giỏi và hết vô minh thì cho mình tạ lỗi. Bài tiếp theo sẽ bàn về mua sách, Tuấn sẽ chia sẻ những kinh nghiệm cá nhân trong việc lựa chọn và mua sách thế nào.

Categories
Review sách software Tech Startup Technology

Review sách “Product-Led Growth” của Wes Bush

Hôm nay review đến mọi người cuốn sách tiếng Anh mà đọc không rời mắt và hoàn thành sau một ngày chỉ với vài tiếng và có thể nói đọc nhanh hơn cả tiếng Việt. Bởi tính chất hấp dẫn và hữu ích của sách này nên dành hẳn 2 tiếng để làm sketch note và chia sẻ với mọi người để cùng tham khảo cũng như giúp các bạn dễ dàng quyết định mua sách này. Đó là cuốn “Product-Led Growth: How to Build a Product That Sells Itself” của Wes Bush.

Sách này gồm 3 phần và phần nào cũng cực kỳ hấp dẫn. Phần đầu nói về việc đánh giá và so sánh giữa công ty product-led và sales-led để giúp bạn đưa ra quyết định tiếp cận phù hợp với mô hình tổ chức cũng như đặc thù sản phẩm và thị trường. Phần tiếp theo nói về phương pháp tiếp cận khách hàng và phần cuối là phương pháp tối ưu hệ thống bán hàng, marketing.

Nếu bạn nào đang hoặc sắp tham gia lĩnh vực cung cấp phần mềm, đặc biệt là Saas như Tuấn thì sẽ không nên bỏ qua cuốn sách này vì có rất nhiều thông tin cực kỳ bổ ích. Từ lên chiến lược phát triển sản phẩm, chiến lược giá cũng như chiến lược marketing để mang lại khách hàng, doanh thu và lợi nhuận cho công ty.

Bên dưới là ghi chú cho từng phần từ sách, và mỗi chương trong sách cũng sẽ được chụp cận cảnh để giúp bạn thấy rõ hơn các nội dung chi chú của Tuấn. Xin thứ lỗi nếu chữ viết không rõ, tuy nhiên, nếu thấy nội dung hay thì bạn có thể mua để ủng hộ tác giá, sách có rất nhiều ví dụ và nội dung hay mà phần ghi chú mình chia sẻ trên đây không đề cập như các chương liên quan đến những sai lầm mắc phải khi cải tiến..

Ghi chú về phần 1

– So sánh mô hình giữa chiến lược sales-led và product-led để cho thấy hai cách tiếp cận khác nhau của việc phát triển sản phẩm.

Sanh sánh 2 mô hình sales-led và product-led và vì sao trong một công ty theo product-led thì các bộ phận đều hướng tới sản phẩm (product).
Dựa vào đặc thù sản phẩm và mô hình kinh doanh mà có các chiến thuật tiếp thị khác nhau để đem lại lợi thế cạnh tranh.
Hai hướng tiếp cận bán hàng khác nhau đó là Top-Down và Bottom-Up. Đối với doanh nghiệp làm Saas thì tốt nhất là theo chiến lược Bottom-Up bởi sẽ dễ dàng tiếp cận với tập khách hàng lớn, tiết kiệm chi phí và có thể dự đoán được doanh thu.

Ghi chú về phần 2

Mô hình UCD hướng đến khách hàng để đưa ra những thông tin phù hợp đến khách hàng.
Hiểu được các giá trị của sản phẩm bạn mang lại cho khách hàng.
Các chiến lược giá để giúp bạn đưa ra những bảng giá tính năng phù hợp nhất cho sản phẩm của mình và kèm theo nhiều phương pháp định lượng, định tính để giúp bạn ra bảng giá phù hợp nhất.

 

Phương pháp tối ưu để đem lại giá trị như đã truyền thông đến khách hàng.

Ghi chú về phần 3

Đây là phần được đánh giá là hay nhất và có nhiều kiến thức thực tế nhất để làm theo và áp dụng nhằm tối ưu hệ thống marketing và bán hàng.
Mô hình ICE để tìm ra những tính năng sẽ đem lại hiệu quả cao nhất giúp cải tiến sản phẩm.
Áp dụng The Bowling Alley Framework để tăng số lượng khách hàng.
Một số phương pháp để tối ưu doanh thu trung bình trên một người dùng (ARPU)
Phân loại churn và một số phương pháp giúp giảm tỷ lệ churn để hạn chế ảnh hưởng đến việc thất thoát doanh thu.

 

Đọc thêm về sách này tại https://www.amazon.com/Product-Led-Growth-Build-Product-Itself/dp/1798434520.

Hiện tại Tuấn vẫn luôn tìm kiếm những bạn có kinh nghiệm trong lĩnh vực marketing và growth, đặc biệt cho các sản phẩm phần mềm Saas. Nếu bạn quan tâm có thể email tới [email protected] để trao đổi thêm nhé.

Categories
Review sách software Technology

Review sách “The Mythical Man-Month” của Frederick P. Brooks

Tuần này mình sẽ review một cuốn sách khá hay dành cho các project manager có tựa là “The Mythical Man-Month”. Cuốn sách này lần đầu xuất bản 1975, tính ra cũng được 45 năm. Tuy đã viết từ lâu như vậy nhưng hầu hết những kinh nghiệm, quan sát và kết luận vẫn còn đúng cho ngành phát triển phần mềm hiện nay.

Brooks là một cây đa cây đề trong ngành phần mềm và thời điểm viết sách này (1975) là ông đang quản lý team phần mềm tại IBM. Cá nhân mình lập trình hơn 15 năm và quản lý nhiều dự án thì thấy những tư tưởng của tác giả đến nay vẫn dùng được. Sách viết từ 1975 nên tiếng Anh thời đó đọc tra từ điển cũng đuối vì có nhiều từ, mẫu câu đã cũ hoặc khá hàn lâm, đọc cũng nhức não mới hiểu nổi ý nghĩa.

Sách gồm 17 chương, trong đó có 4 chương mới được viết thêm vào 1995 nhân kỷ niệm 20 năm xuất bản. Sách này chình là khởi nguồn cho định luật Brooks cũng khá nổi tiếng là “Adding manpower to a late software project makes it later” (Đưa thêm người vào 1 dự án đang trễ, sẽ chỉ khiến nó càng trễ hơn).

Sách bao gồm những bài luận ngắn, riêng lẻ về các đề tài xoay quanh việc quản lý dự án phần mềm như về tài nguyên hệ thống, phần cứng, đội nhóm, nhân sự, dự án, tài liệu nội bộ, manual cho người dùng, sự thay đổi trong cấu trúc tổ chức, cũng như những khó khăn trong xây dựng phần mềm mà sẽ không có phương pháp triệt để nào giải quyết dứt điểm.

Chương mình thích hơn hết là Chương 2 (The Mythical Man-Month, cũng là tựa sách luôn) và chương 16 (No Silver Bullet – Essence and Accident in Software Engineering). Chương 2 là khởi nguồn cho định lý Brooks, liên quan đến việc phân tích sự liên hệ giữa nhân sự và thời gian (Man-month) và chỉ ra những trường hợp nào thì việc tăng người mới hiệu quả và cũng giải thích tại sao không hiệu quả trong những trường hợp khác. Chương 16 bàn về khó khăn khi triển khai cũng đưa ra nhiều góc nhìn và quan điểm khiến cho việc phát triển phần mềm sẽ luôn gặp khó khăn bởi có nhiều vấn đề là không thể thay đổi hay có giải pháp tối ưu để giải quyết.

Ngoài hai chương này ra, thì các chương khác bàn về documentation, manual cũng rất hay. Có hai khái niệm khác được đề cập và đến nay thấy hữu ích là “Conceptual Integrity” (yêu cầu cho thiết kế hệ thống) và “Second-System Effect” (các bạn startup sẽ thấy chương này hữu dụng vì nó chỉ ra hiệu ứng second-system, khiến cho việc bạn xây dựng những hệ thống quá phức tạp, ảnh hưởng đến thời gian release dự án bởi vì bạn…quá giỏi giang trước đó – thành công của First system).

Bên dưới là nội dung tóm lượt của Chapter 2 (The Mythical Man-Month) mình copy ra đây để các bạn lấy ý tưởng.

2. The Mythical Man-Month

2.1 More programming projects have gone awry for lack of calendar time than for all other causes combined.

2.2 Good cooking takes time; some tasks cannot be hurried without spoiling the result.

2.3 All programmers are optimists: “All will go well.”

2.4 Because the programmer builds with pure thought-stuff, we expect few difficulties in implementation.

2.5 But our ideas themselves are faulty, so we have bugs.

2.6 Our estimating techniques, built around cost-accounting, confuse effort and progress. The man-month is a fallacious and dangerous myth, for it implies that men and months are interchangeable.

2.7 Partitioning a task among multiple people occasions extra communication effort-training and intercommunication.

2.8 My rule of thumb is 1/3 of the schedule for design, 1/6 for coding, 1/4 for component testing, and 1/4 for system testing.

2.9 As a discipline, we lack estimating data.

2.10 Because we are uncertain about our scheduling estimates, we often lack the courage to defend them stubbornly against management and customer pressure.

2.11 Brooks’s Law: Adding manpower to a late software project makes it later.

2.12 Adding people to a software project increases the total effort necessary in three ways: the work and disruption of repartitioning itself, training the new people, and added intercommunication.


Sách có thể mua trên Amazon. Chúc mọi người một tuần vui vẻ.

Categories
Technology

Xây dựng hệ thống Log cho Microservices

Hôm qua mình có làm speaker chia sẻ về kiến trúc hệ thống Log của Teamcrop.com, thấy nhiều bạn hưởng ứng và quan tâm quá nên mình khai trương blog năm mới bằng một bài viết ngắn nói về chủ đề này.

Xây dựng hệ thống log được đánh giá rất quan trọng, đặc biệt đối với các hệ thống đang trong giai đoạn tăng trưởng người dùng và mở rộng tính năng. Có nhiều hướng tiếp cận khác nhau để triển khai hệ thống log, từ việc sử dụng các dịch vụ Saas có sẵn, không cần cài đặt hay server gì như các hệ thống Loggly, DataDog, Papertrail…cho tới các open source như Graylog, ELK (ElasticSearch, Logstash, Kibana) Stack, Grafana…Tuy nhiên, do đặc thù của dữ liệu, số lượng log và tốc độ truy xuất mà Teamcrop buộc phải thiết kế một hệ thống log riêng để giải quyết các vấn đề về chi phí lưu trữ và vận hành.

Để xây dựng hoặc tìm hiểu một hệ thống Log, chúng ta cần thấy được các thành phần của hệ thống Logging bởi performance và tính tiện dụng đều dựa vào mô hình hệ thống Log. Mình tạm chia một hệ thống Log thành ba thành phần cơ bản là Collector, Storage và Dashboard.

  • Collector là phân hệ chịu trách nhiệm thu thập dữ liệu log từ các nguồn cung cấp (syslog, access log, error log, api request, sql query..)
  • Storage là thành phần sẽ lưu trữ dữ liệu log, có thể là tạm thời hoặc vĩnh viễn, ví dụ như RabbitMQ (tạm thời), File System (tạm thời), MySQL, Clickhouse…
  • Dashboard là thành phần sẽ truy xuất vào storage và hiển thị dữ liệu bao gồm data table, biểu đồ, dashboard…đến đối tượng cần coi log.

Để dễ dàng tiếp cận với các vấn đề của Log, trước tiên chúng ta cần phân loại log vì mỗi loại log sẽ có đặc tính khác nhau về số lượng cũng như cách truy xuất, sử dụng. Mình tạm phân loại Log thành 2 loại: Business và Operation Log.

Business Log

Business Log là những loại log giúp hỗ trợ các hoạt động và quyết định của doanh nghiệp. Như các Usage Log liên quan đến sử dụng các tính năng trên giao diện để bộ phận marketing, product dễ dàng ra quyết định liên quan đến kinh doanh và phát triển sản phẩm. Đối với loại log này thì hiện tại có ông trùm và được sử dụng khá nhiều là Google Analytics. Nếu cần open source thì có thể sử dụng Matomo (tiền thân là Piwik) để cài đặt trên server của bạn, tính năng của Matomo cũng gần như Google Analtyics.

Một loại Business Log khác mà mình đề cập trong phần chia sẻ là Critical Function Log dành cho những nghiệp vụ quan trọng, giúp đảm bảo an toàn cho hệ thống và khôi phục được trong trường hợp sự cố xảy ra và có thể tạo được dữ liệu. Log này quan trọng vì trong một kiến trúc Microservices thì có thể do cấu hình, cài đặt hoặc lỗi hệ thống khiến cho 1 service có thể bị cô lập và không gọi được các service khác trong quá trình thực thi. Ví dụ như tạo đơn hàng (service Đơn hàng) sẽ gọi các service như Sản phẩm, Tồn kho, Khách hàng, Thu chi…để hỗ trợ quá trình tạo đơn hàng. Nếu trong quá trình tạo đơn hàng mà toàn bộ các service khác không thể truy cập thì service Đơn hàng sẽ có một cơ chế an toàn riêng để đảm bảo dữ liệu request lên (raw POST data) được backup tạm thời phòng trường hợp cực hạn này. Số lượng tính năng áp dụng cơ chế log này là không lớn.

Loại log cuối cùng trong nhóm Business Log mà mình muốn đề cập là Auditing Log. Loại log này khá là quan trọng và nếu bạn đang phát triển các hệ thống Enterprise không thể bỏ qua. Auditing Log giúp doanh nghiệp có thể dễ dàng phát hiện các hoạt động bất thường, quan trọng (như xóa, import, export dữ liệu…) để kịp thời có hướng xử lý. Auditing Log còn có thể thiết kế như một hệ thống Change Log để lưu lại lịch sử thay đổi dữ liệu của 1 record (như đơn hàng, khách hàng…). Nếu có tìm hiểu về Microservices thì các bạn sẽ thấy cách thức lưu change log này của Auditing Log khá giống với pattern Event Sourcing (ES) trong mô hình CQRS/ES.

Trong hầu hết trường hợp thì chúng ta ít khi tập trung vào tự xây dựng business log bởi đối với loại này phải được phân tích kỹ và chỉ định cụ thể dịch vụ nào, tính năng nào cần được log (Auditting, Critical, Usage) để tiến hành lập trình nâng cấp.

Operation Log

Nhóm log thứ hai được đánh giá là có tác động to lớn đến quá trình tối ưu, cải tiến hệ thống là Operation Log. Một số loại log thuộc nhóm này bao gồm: Operating System, General Log, API Request, SQL Query và Distributed Tracing.

Operating System Log là nhóm log cơ bản giúp theo dõi và đánh giá tình hình chung của hệ thống như ổ cứng, memory, cpu, network IO…đối với nhóm log này thường đi kèm với hệ thống monitoring và bên Teamcrop sử dụng NodeQuery.com để theo dõi vì hệ thống NodeQuery khá tốt và đơn giản, kèm với giao diện dashboard rất dễ dùng và cơ chế alert hiệu quả. NodeQuery cũng được rất nhiều công ty trên thế giới sử dụng.

Loại log tiếp theo trong nhóm Operation Log là General Log, bao gồm những Log liên quan đến hoạt động của Nginx, PHP…và những custom log message do bạn ghi xuống trong quá trình vận hành hoặc debug hệ thống. Cùng với API Request Log, SQL Query Log thì mình tự xây dựng cơ chế log riêng bởi số lượng và tần suất log rất cao, việc sử dụng các hệ thống khác hoàn toàn không hiệu quả về hiệu suất và kinh tế.

API Request Log là loại log để theo dõi toàn bộ các request vào hệ thống Microservices. Giúp bộ phận lập trình biết được performance của các request như thời gian thực thi một tính năng (execution time) cũng như memory cấp phát cho các tính năng.

SQL Query Log cũng là loại log có mục đích khá giống với API Request Log, giúp lập trình viên và DB Admin có thể theo dõi được tình hình truy vấn database, câu truy vấn nào chưa tối ưu, table nào được truy cập nhiều, tình trạng tỷ lệ master/slave trong mô hình replicate có duy trì ở mức ổn định hay không…

Cuối cùng là một loại log cực kỳ cần thiết trong quá trình vận hành một hệ thống Microservices, đó là Distributed Tracing. Hầu hết các bạn khi chuyển sang kiến trúc Microservices, sẽ hay bị trình trạng service gọi lồng vào nhau, A –> B —> C —> D thì khi có một lỗi hoặc bottleneck nào đó ở một service bên trong (vd service C) thì rất khó phát hiện và debug bởi đặc thù phân tán của kiến trúc Microservices. Để giải quyết vấn đề này thì kỹ thuật Distributed Tracing sẽ giúp ích rất nhiều. Teamcrop sử dụng Zipkin Library PHP dùng để format dữ liệu theo đặc tả OpenTracing và backend sử dụng Jaeger (dự án Open source của Uber).

Đó là toàn bộ những chia sẻ của Tuấn tại buổi meetup đầu năm 2020 ngày 09/01/2020. Bên dưới là phần Slide trình bày (có cải tiến cho dễ hiểu hơn).


Dưới đây là schema của 3 table tương tứng với 3 loại log (General Log, API Request Log và SQL Query Log) được tạo trong database ClickHouse:

CREATE TABLE log_request (
  lr_date Date,
  lr_datetime DateTime,
  lr_hour UInt8,
  lr_minute UInt8,
  lr_service String,
  lr_method String,
  lr_controller String,
  lr_action String,
  lr_companyid UInt32,
  lr_userid UInt32,
  lr_status UInt16,
  lr_exectime Float32,
  lr_memory Float32,
  lr_ip String,
  lr_depth UInt8,
  lr_source String,
  lr_traceid String,
  lr_tracespanid String
) ENGINE = MergeTree(lr_date, (lr_datetime, lr_hour, lr_minute, lr_service, lr_method, lr_controller, lr_action, lr_companyid, lr_userid, lr_status, lr_exectime, lr_memory, lr_ip, lr_depth, lr_source, lr_traceid, lr_tracespanid), 8192);;


CREATE TABLE log_sql (
  ls_date Date,
  ls_datetime DateTime,
  ls_hour UInt8,
  ls_minute UInt8,
  ls_hosttype String,
  ls_host String,
  ls_querytype String,
  ls_table String,
  ls_exectime Float32,
  ls_companyid UInt32,
  ls_userid UInt32,
  ls_traceid String,
  ls_tracespanid String
) ENGINE = MergeTree(ls_date, (ls_datetime, ls_hour, ls_minute, ls_hosttype, ls_host, ls_querytype, ls_table, ls_exectime, ls_companyid, ls_userid, ls_traceid, ls_tracespanid), 8192);


CREATE TABLE log_syslog (
  ls_date Date,
  ls_datetime DateTime,
  ls_hour UInt8,
  ls_minute UInt8,
  ls_message String,
  ls_tag String,
  ls_host String,
  ls_source String
) ENGINE = MergeTree(ls_date, (ls_datetime, ls_hour, ls_minute, ls_message, ls_tag, ls_host, ls_source), 8192);

P.S: Teamcrop.com là hệ thống phần mềm quản lý bán hàng và nhân sự, nếu bạn nào quan tâm thì có thể dùng thử và ủng hộ một startup hoàn toàn Việt Nam nhé. Nếu bạn nào hứng thú với PHP hoặc kiến trúc Microservices, thì có thể cùng tham gia xây dựng Teamcrop với Tuấn, mọi thông tin gửi vào email trong trang cuối của Slide ở trên nhé.

Categories
Miscellaneous

New Year’s Resolution of 2020

Năm 2019 đã đến những giờ phút cuối, đến hẹn lại lên thì thời điểm này lại ngồi nhìn lại một năm đã trải qua và tự đánh giá để rút tỉa kinh nghiệm cũng như sau này nếu có giảm trí nhớ thì cũng biết mình đã từng trải qua những gì.

2019 – Tiếp tục tiến tới

Về kinh doanh thì 2019 tạm gọi là “đủ ăn” chứ không dư dả gì vì đúng là năm bản lề tăng trưởng. Ít ra, sau 6 năm thành lập thì công ty vẫn tồn tại tốt và biểu đồ có chiều hướng đi lên dần đều chứ không đi xuống tịt ngòi. Công ty vẫn kiên định với 2 mảng kinh doanh chính là Software-as-a-Service (SaaS) và Outsourcing, cả 2 mảng đều tập trung vào tầm nhìn từ ban đầu của công ty là “Số hóa vận hành của doanh nghiệp”.

Trong nhánh SaaS thì Teamcrop, Basecrop thì vẫn tăng trưởng đều. Đặc biệt, hệ thống tăng trưởng tốt nhất đó là Movecrop. Chatcrop thì đã chấm dứt sớm sau khoảng 3 tháng giới thiệu vì mình cũng không đặt nặng vào mảng chatbot và messaging, bu bám các social platform. Bạn Helpcrop cũng sớm ra đi sau đó ít lâu sau khi không có traction. Với phương châm “Try very fast, Fail very fast” thì không có thiệt hại gì đáng quan tâm bởi các dự án đã fail.

Trong nhánh Outsourcing thì tập trung chính vào mảng xây dựng các hệ thống thương mại điện tử trên nền tảng web & mobile app. Bắt đầu nhận các dự án liên quan đến AI/Machine Learning.

Về gia đình thì con cái khỏe mạnh, vợ chồng hòa thuận, ai cũng được làm được cái mình thích là vui rồi. Vẫn phương châm 9am-5pm nên có nhiều thời gian ở nhà hơn. Đặc biệt là năm nay là kỷ niệm tròn 10 năm quen được bà xã. Đáng gọi là thành công vang dội rồi.

Về cộng đồng thì cuối năm cũng tham gia được sự kiện nho nhỏ để chia sẻ đến bà con công việc của mình. Năm nay hoạt động cộng đồng khá ít vì tuổi cũng lớn và tập trung xây dựng nền tảng hơn. Để dành nhiều thời gian cho công ty và bản thân hơn.

Về bạn bè thì vẫn những người bạn cũ đã quen biết, không biết thêm nhiều bạn bè mới, nhưng quả thực “Quý hồ tinh bất quý hồ đa”, có được những người bạn hiện tại cũng là một phần may mắn của Tuấn vì với tính khí khùng điên như mình mà mấy chế vẫn giữ được bình tĩnh thì các bạn thật vĩ đại.

Về cá nhân thì vẫn vui vẻ, được làm việc trong một môi trường thân thiện, hòa đồng và đọc được khá nhiều sách. Năm nay đọc nhiều sách tiếng Anh và chuyên ngành hơn, dù không đạt chỉ tiêu 100 cuốn sách (chỉ khoảng 70 cuốn) và sẽ cố gắng đọc nhiều hơn trong 2020. Cũng đi du lịch nước quài được 2 lần để đạt yêu cầu tối thiểu của việc đi chơi.

Tóm lại thì 2019 là một năm đạt một số thành tựu nho nhỏ, từ hoạt động kinh doanh đến phát triển bản thân, nên 12 tháng vừa qua khá ưng ý và không có gì hối tiếc.

Hứa hẹn vào 2020

Nối tiếp sự tăng trưởng của 2019 thì hy vọng 2020 sẽ mang lại nhiều thành tựu hơn, từ kinh tế đến trình độ phát triển bản thân. Dù biết rằng các chỉ tiêu đặt ra có thể khó đạt được, nhưng vẫn mạnh dạn đặt ra một số chỉ tiêu để đeo đuổi như:

  • Triển khai 10 dự án Outsourcing
  • Đọc 200 cuốn sách
  • Công ty tăng 50% nhân sự.
  • Viết blog mỗi tuần 1 bài.
  • Tham gia meetup chia sẻ 1 lần / tháng
  • Đi du lịch quốc tế 4 lần, và cố gắng có 1 lần đi Mỹ
  • Ra mắt 3 dự án mới trong mảng công nghệ.
  • Phấn đấu đạt một chứng chỉ quốc tế nào đó.

Và cuối cùng, chúc mọi người một năm 2020 tràn đầy sức khỏe, may mắn và thành công. Happy New Year!

Categories
DevOps

Speed up Microservices 4: Asynchronous Big Task

Nối tiếp nội dung về tối ưu cho kiến trúc Microservices, lần này mình sẽ đề cập đến một bài toán cũng gặp rất nhiều và có thể coi là giải pháp khác của bài trước là Export dữ liệu. Nếu như ở bài trước, việc export dữ liệu được diễn ra ở Frontend (JS) bao gồm tải dữ liệu có phân trang và đóng gói excel thì có những hạn chế sau:

  • Nếu dữ liệu nhiều sẽ ảnh hưởng đến frontend vì memory có giới hạn
  • Quá trình export này là đồng bộ, tức là nếu đóng tab hoặc reload trang là tải lại từ đầu
  • Tính năng cần xuất dữ liệu này chưa có giao diện frontend, kéo theo thêm việc làm (làm trang danh sách) nếu chỉ muốn export.

Do những hạn chế trên nên cách đây ít lâu vẫn còn 1 vài tính năng Export dữ liệu phải được thực hiện ở phía server và rất khó đưa xuống Frontend vì yếu tố phức tạp của lấy dữ liệu và số lượng dữ liệu lớn. Những tính năng export kiểu cũ này kéo theo hạn chế rõ ràng là script sẽ chạy lâu và luôn kích hoạt cơ chế slow log vì có những script chạy cả tiếng đồng hồ chưa xong file excel để export và Memory chiếm vài GB cho 1 process. Nếu chỉ cần vài khách hàng vào thực hiện tính năng Export thì sẽ dẫn đến hệ thống treo, và trong môi trường không kiểm soát được thì làm sao có những yêu cầu dạng “cậu chỉ được export vào lúc X giờ”…

Do những hạn chế của cả 2 hình thức công việc như trên nên Teamcrop đã hoàn thiện giải pháp khá tối ưu, hiệu quả và an toàn cho người và của, và đó chính là nội dung của bài chia sẻ này.

Big Task là gì?

Trước tiên, cần phải định nghĩa Big Task là gì để dễ dàng thảo luận. Big Task ám chỉ những task khi thực hiện sẽ tốn khá nhiều thời gian và tài nguyên (Memory, CPU..). Ví dụ như những tính năng export tồn kho hàng chục ngàn sản phẩm, SKU, import hàng ngàn sản phẩm, đơn hàng, hoặc đi spam email, sms…

Một số đặc điểm của hệ thống BigTask mà Teamcrop đã xây dựng là:

  • Có thể chia nhỏ
  • Kiểm soát được tiến độ công việc (Bao nhiêu % hoàn thành..)
  • Bất đồng bộ: người dùng có tắt trình duyệt hay tắt máy thì hệ thống vẫn cứ làm việc
  • Có khả năng retry

Big Task được vận hành thế nào?

Tất nhiên, mỗi task bây giờ được định nghĩa là một row trong Database, mỗi task sẽ có 3 giai đoạn:

  • Bước 1: Chuẩn bị
  • Bước 2: Xử lý dữ liệu
  • Bước 3: Kết thúc

Bước chuẩn bị thường được trigger bởi người dùng và từ giao diện frontend, như submit form chứa thông tin. Ở bước chuẩn bị này chính là giai đoạn quan trọng nhất, bao gồm khởi tạo tổng số record cần xử lý (để kiểm soát progress), ghi nhận các cấu hình cần thiết cho task như số lượng record cần xử lý 1 trang, các dữ liệu cài đặt khi người dùng submit form và một bước quan trọng là khởi tạo 1 file excel chỉ có header (không có dữ liệu) ở môi trường local.

Bước xử lý dữ liệu là công việc chính liên quan đến nhiệm vụ, như lấy dữ liệu để insert vào file excel theo từng batch, ví dụ nếu task được giao mỗi trang lấy 100 record thì chỉ lấy 100 record và đẩy nhiệm vụ trang tiếp theo vào Messsage Queue (ví dụ RabbitMQ), hệ thống Queue worker sẽ chịu trách nhiệm thực thi trang tiếp theo dựa vào nội dung trong message đã được đẩy vào queue.

Bước kết thúc chính là đảm bảo dữ liệu đã đầy đủ và đưa các file cần thiết vào hệ thống, đối với Teamcrop là gọi File Service để lưu file tạm ở trên, thông báo và kết thúc task để đánh dấu task hoàn tất.

Như vậy, với sự giúp đỡ của kiến trúc Message Queue thì những task lớn có thể chia nhỏ và tiến trình được kiểm soát, đặc biệt là giúp cho hệ thống không có những script chạy quá lâu và tốn quá nhiều tài nguyên. Hiện tại bên Tuấn đã bắt đầu migrate dần các task dạng này vào mô hình Big Task của mình để tăng performance của hệ thống.

Hy vọng bài viết này sẽ giúp các bạn đối phó với một trong những bài toán đau đầu khi scale.

 

Categories
DevOps

Speed up Microservices 3: Export dữ liệu ra Excel

Chào mọi người, nối tiếp bài trước là tận dụng caching ở trình duyệt để tăng tốc cho microservices. Ở bài này mình sẽ chia sẻ một case study khá thông dụng trong các dự án “vừa vừa”, đó là nhu cầu export dữ liệu ra file excel. Nếu như các bạn thường xuyên làm việc liên quan đến các hệ thống quản lý dữ liệu thì data table / grid sẽ xuất hiện khá nhiều, kéo theo tính năng thường xuyên được yêu cầu là export dữ liệu (ra file Excel).

Categories
Web Programming

MySQL ngoại truyện

Cuối tuần vừa rồi mới vừa clear gần 50% table trong database của Teamcrop, đây là những table của những tính năng không còn sử dụng và đã trải qua thời gian deprecated (chờ xử trảm), thấy có lẽ nên viết một bài về database nhân dịp đầu năm mới cũng như khai blog 2019.

Cũng giống như nhiều đàn anh, đàn chị thời nay, mình đã sớm tiếp xúc với PHP từ 2003 khi xu hướng diễn đàn lớp, diễn đàn trường, diễn đàn vớ vẫn nở rộ. Những đoạn code đầu tiên là những mod diễn đàn viết bằng PHP, cũng như những câu truy vấn database MySQL đầu tiên cũng xuất hiện từ thời điểm này. Bài viết mang tính chất cổ súy MySQL nói riêng (RDBMS nói chung) nên nếu ai không biết nó là gì thì nên tìm hiểu hoặc làm với nó ít ít rồi hẳn đọc tiếp và đối tượng bài viết có thể là DB Administrator hoặc Developer có nhiệm vụ làm việc với MySQL, hầu hết chúng ta – web developer cũng là những người maintain database schema.

Làm việc với MySQL hơn 15 năm (và hiện nay vẫn chỉ tin và dùng MySQL), nên ít nhiều có chút kinh nghiệm khi sử dụng cũng như hình thành những quy trình, đường lối cho cá nhân và team khi tham gia xây dựng dự án. Mỗi khi có Web developer mới tham gia vào công ty thì những kiến thức này lại được truyền đạt, tuy nhiên đó giờ vẫn chưa có một tài liệu cụ thể nên bài blog này cũng là một phần phục vụ việc training này.

Tại sao lại gọi là ngoại truyện?

Hầu hết những gì mình chia sẻ ở đây có thể các bạn sẽ rất ít thấy đề cập ở các sách hay giáo trình về MySQL. Thậm chí có những thứ có thể được coi là đi ngược với những gì bạn biết về MySQL.

Để dễ chia sẻ thông tin, mình sẽ tách thành 3 giai đoạn khi các bạn làm việc với MySQL, đó là trước khi có dữ liệu (data), trong khi có dữ liệu và khi không còn dữ liệu. Ở mỗi giai đoạn sẽ có những kinh nghiệm khác nhau và phù hợp với ngữ cảnh để mọi người tiện theo dõi.

1. Trước khi có dữ liệu

Theo quan sát và kinh nghiệm, rất nhiều bạn khá hời hợt và xem thường giai đoạn này, tức giai đoạn phân tích và thiết kế database, hay nói 1 cách dân dã là tạo bảng (CREATE TABLE..). Rất nhiều vấn đề phát sinh bởi việc thiết kế bảng hời hợt, thậm chí là thiết kế sai, kéo theo technical debt sẽ ngày càng lớn và thậm chí là phải bỏ cả tính năng / bảng đang sử dụng để refactoring lại thành tính năng mới, tạo table mới và migrate dữ liệu từ bảng cũ sang bảng mới.

Ngoài việc thiết kế bảng đúng, duy trì tính dễ hiểu (understandable), dễ bảo trì (maintainable) và đồng nhất (consistent) cũng là một số yếu tố luôn được cân nhắc khi thiết kế một table. Bên dưới là một số “guideline” mà ai muốn tham gia vào team của Tuấn sẽ được training và bắt buộc phải theo:

Về database:

  • Trong một Database, tất cả tên bảng phải có tiền tố giống nhau (prefix). Ví dụ: crp_, abc_…
  • Để tăng khả năng chuyển đổi DBMS và tương thích với các hệ SQL, không sử dụng các khái niệm “phức tạp” của database như Store procedure, View, Constraint
  • Không sử dụng khái niệm ràng buộc khóa chính, khóa ngoại cài đặt trong DBMS. Chỉ sử dụng khái niệm này trong quá trình trao đổi thông tin giữa các developer và thiết kế bảng.
  • Áp dụng kiến trúc Microservices để chia nhỏ database theo từng domain/context riêng để giúp giảm tải chung cho toàn Database. Ví dụ: Mỗi service sẽ cần 1 kiến trúc / server DB riêng để vận hành riêng biệt.
  • Những phiên bản MySQL khác nhau sẽ có một số config khác nhau kéo theo những lỗi không ngờ tới khi nâng cấp phiên bản.
  • Không sử dụng docker / VM cho MySQL Server.

Về bảng (table):

  • Khi đặt tên bảng, tên cột thì không sử dụng chữ HOA hoặc ký tự đặc biệt. Cho phép a-z, 0-9 và underscore (gạch dưới “_”).
  • Tên bảng luôn là tiếng anh và sử dụng từ số ít. Ví dụ: crp_product, crp_news
  • Nếu tên bảng là tổ hợp nhiều từ, thì mỗi từ cần cách nhau gạch dưới (underscore). Ví dụ: abc_product_category, abc_order_detail
  • Trừ các cột khóa ngoại, các cột dữ liệu riêng của một bảng luôn có tiền tố giống nhau, và tổng hợp từ chữ cái đầu tiên của tên bảng (không bao gồm tiền tố database). Ví dụ: bảng abc_product_category thì các cột của bảng này phải có tiền tố là “pc_”, như “pc_id”, “pc_name”..
  • Tên cột ngoài tiền tố bảng thì là các từ tiếng anh, số ít và không có khoảng cách, các từ phải viết liền nhau. Ví dụ: p_countview, p_datecreated..
  • Khóa chính của một cột trong bảng luôn là tiền tố của bảng + “id”. Ví dụ: “pc_id”, “p_id”, “n_id”..
  • Khóa ngoại của một bảng sẽ được nằm đầu tiên trong danh sách cột của bảng này, trước cả cột khóa chính. Tên cột khóa ngoại phải giữ nguyên tên cột mà nó làm khóa chính trong bảng của nó. Ví dụ: u_id là User ID và là khóa chính trong bảng “abc_user”, thì khi làm khóa ngoại trong bảng “abc_product” thì nó vẫn là cột “u_id”.
  • Collation của database / table / text column là “utf8_general_ci”
  • Table luôn có engine mặc định là MyISAM (tối ưu cho SELECT dữ liệu)
  • Có thể tận dụng engine MEMORY để tối ưu truy vấn vì toàn bộ dữ liệu của table loại MEMORY sẽ nằm trong RAM thay vì ổ cứng.

Về kiểu dữ liệu của cột trong bảng:

  • Kiểu dữ liệu của khóa ngoại và khóa chính phải trùng khớp nhau (data type & data length)
  • Không sử dụng kiểu dữ liệu DATETIME trừ trường hợp lưu ngày sinh.
  • Không sử dụng kiểu dữ liệu ENUM trong trường hợp cần lưu theo logic này, chỉ cần lưu INT (11) hoặc SMALLINT(3) và trong Model của code sẽ khai báo constant.
  • Tất cả cột thời gian đều lưu Timestamp và kiểu dữ liệu INT(10).
  • Các cột dữ liệu thời gian luôn là những cột nằm cuối cùng của bảng. Hầu hết các bảng luôn có cột: datecreated (ngày tạo) và datemodified (ngày cập nhật).
  • Trường IP Address luôn là BIGINT (20), và sử dụng hàm ip2long() và long2ip() của PHP để encode/decode.
  • Giá trị tiền nên là DECIMAL (18), tốt nhất là DECIMAL (18,4)
  • Cẩn thận khi thiết kế dữ liệu cho việc lưu ký tự emoji.

Việc tuân thủ các guideline này sẽ giúp rất nhiều trong việc debug cũng như đoán được nguồn gốc, xuất xứ của 1 cột khi làm việc, và tạo sự nhất quán trong toàn team để dễ trao đổi, debug. Ví dụ bên dưới là thiết kế cho table user, product.

CREATE TABLE `crp_user` (
  `u_id` int(11) NOT NULL,
  `u_email` varchar(128) NOT NULL,
  `u_password` text NOT NULL,
  `u_ipaddress` bigint(20) NOT NULL,
  `u_status` smallint(3) NOT NULL,
  `u_datecreated` int(10) NOT NULL,
  `u_datemodified` int(10) NOT NULL,
  `u_datelastloggedin` int(10) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


CREATE TABLE `crp_product` (
  `u_id` int(11) NOT NULL,
  `p_id` int(11) NOT NULL,
  `p_name` varchar(255) NOT NULL,
  `p_description` text NOT NULL,
  `p_price` decimal(18,4) NOT NULL,
  `p_status` smallint(3) NOT NULL,
  `p_ishot` tinyint(1) NOT NULL,
  `p_datecreated` int(10) NOT NULL,
  `p_datemodified` int(10) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Với những tiêu chí trên thì đảm bảo team bạn sẽ dễ dàng làm việc trên các bảng dữ liệu của các dự án.

2. Trong khi có dữ liệu

Sau quá trình thiết kế bảng hoàn tất và đã được đưa lên hệ thống, tính năng cũng đã được chạy và bạn bắt đầu có dữ liệu, không gì tuyệt hơn là có dữ liệu. Đến giai đoạn này, việc duy trì cho hệ thống đang chạy là ưu tiên hàng đầu, và một số chia sẻ ở giai đoạn này cũng nhằm giúp việc đảm bảo hệ thống DB không bị gián đoạn.

  • Không thay đổi tên cột trong bất kì tình huống nào.
  • Không xóa cột trong bất kì tình huống nào.
  • Chỉ đổi kiểu dữ liệu cột sang cùng loại và sang dung lượng lớn hơn. Ví dụ cho phép đổi từ VARCHAR(50) -> VARCHAR (100), SMALLINT(3) -> INT (11).
  • Cần áp dụng replicate database (Master / Slave) dữ liệu để giảm tải. Để tránh rắc rối không cần thiết, chỉ nên sử dụng 1 Master và có thể cho phép nhiều Slave.
  • Trong bất kì tình huống nào liên quan đến vấn đề đồng bộ giữa Master & Slave và liên quan đến lỗi đồng bộ binlog, tốt nhất là disable replicate, chỉ sử dụng Master, tìm ra nguyên nhân cụ thể để khắc phục và phần lớn vấn đề liên quan đến networking, ổ cứng mạng, tắt bất tử.
  • Lưu ý “Delay Gap” (thời gian bất đồng bộ dữ liệu) giữa Master và Slave(s).
  • Đồng bộ dữ liệu vào thời gian ít truy cập nhất
  • Backup dữ liệu định kì và upload lên một hệ thống / server khác hệ thống đang chạy. Bên mình kết hợp S3cmd để đẩy file backup sql lên Amazon S3 để backup mỗi ngày.
  • Tuyệt đối lưu ý đến max connection mặc định của MySQL là 150 để tránh lỗi MySQL connection.
  • Nếu cài đặt max connection lớn thì lưu ý việc MySQL server sẽ block IP do cơ chế security.
  • Hạn chế đến mức tối đa việc sử dụng JOIN TABLE để tăng khả năng refactoring, migration cũng như giảm thiểu vấn đề về performance / SQL execution. Chỉ JOIN khi đây là hoạt động bất khả kháng và không còn phương án nào tối ưu hơn cho việc truy vấn (tìm kiếm).
  • Không sử dụng JOIN cho các entity không liên quan đến nhau hoặc cùng 1 domain/service. VD: không join user & comment, product & comment..Có thể JOIN order & order detail.
  • Luôn có Cache layer ở tầng Application (Redis, memcached) để hạn chế truy vấn vào Database cũng như hỗ trợ việc hạn chế JOIN.

3. Khi dữ liệu không cần thiết

Hầu hết dự án nào cũng có những tính năng “không còn sử dụng” và có nhu cầu xóa bỏ luôn dữ liệu thì bạn cũng cần có những quy định cho việc này. Vì sao phải xóa dữ liệu? Theo thời gian, giữ liệu sẽ ngày một phình to, nếu vẫn cố giữ những dữ liệu không còn sử dụng thì sẽ kéo theo thời gian backup / migration / recovery lớn hơn, dẫn đến nhiều rủi ro tiềm ẩn không cần thiết, do đó, tốt nhất là xóa những gì không dùng. Hoặc nếu muốn giữ lại thì cũng nên tách data này sang 1 nơi mà không ảnh hưởng đến performance / rủi ro chung của toàn hệ thống.

Bên dưới là một số bước mà bên mình dùng để xóa dữ liệu, các bạn có thể tham khảo và áp dụng.

  • Bởi vì không có cài đặt ràng buộc tự động (Constraint) nên tầng Application cần có các tính năng (cronjob) tự động để xóa các dòng dữ liệu không cần thiết hoặc update các cột dữ liệu bị lỗi.
  • Đảm bảo các bảng cần xóa không được tham chiếu bởi bất kì tính năng nào. Nếu có tham chiếu thì cần đảm bảo tính năng này hiện đã không còn sử dụng.
  • Kiểm tra ngày cuối cùng mà bảng này có dữ liệu mới, hay modified date của bảng.
  • Không có bảng ngay mà chỉ đổi tên bảng và thêm tiền tố. Ví dụ: thêm OLD_, DEPRECATED_
  • Chờ tối thiểu 1 tháng -> 3 tháng và chỉ xóa các bảng có tiền tố định trước là sẽ xóa.
  • Hạn chế tối đa việc gõ tên bảng, nên copy tên bảng ra trước rồi copy vào CMD.
  • Khi xóa bảng thì không nên dùng MySQL Client / GUI để thao tác mà thông qua MySQL CLI và thực thi SQL mà thôi.
  • Theo dõi hệ thống support / CS tối thiểu 1 ngày để phát sinh những support ticket liên quan đến mất dữ liệu, lỗi tính năng do khách hàng report.

Trên đây là tất cả những quy trình, kinh nghiệm mà team mình áp dụng khi làm việc với MySQL. Hy vọng mọi người cũng có những quy trình để giúp bảo vệ dữ liệu tốt hơn và cải thiện quá trình lưu trữ và làm việc nhóm liên quan đến cấu trúc dữ liệu.

Categories
Miscellaneous

New Year’s Resolution of 2019

Cũng như các năm trước, 31/12 là dịp ngồi review lại những gì đã diễn ra trong năm và 2018 là một năm được đánh giá là “có thu hoạch” về một số mặt quan trọng trong sự nghiệp và đời sống.