- vừa được xem lúc

Một số lỗi thường gặp về perfomance trong dự án ECCUBE + php

0 0 10

Người đăng: Phan Ngoc

Theo Viblo Asia

1.Lỗi không index làm delete query bị slow.

  • Bối cảnh: Chức năng login có lưu table lock tạm, để xác định số lần nhập sai

  • Nguyên nhân: Khi không có index, truy vấn xóa sẽ phải quét qua toàn bộ bảng để tìm và xóa các hàng thỏa mãn điều kiện, dẫn đến tình trạng lock toàn bộ bảng trong quá trình thực hiện.

A locking read, an UPDATE, or a DELETE generally set record locks on every index record that is scanned in the processing of an SQL statement. (MySQL :: MySQL 8.0 Reference Manual :: 15.7.3 Locks Set by Different SQL Statements in InnoDB)

2.Lỗi muti process tranh nhau barcode, duplicate.

  • Bối cảnh: Mỗi user khi đăng kí sẽ được cấp barcode độc nhất, và có thuật toán sinh ra liên tục trong chuỗi.

  • Nguyên nhân:

Mỗi user được cấp 1 barcode unique, nhưng việc check distinct lại dựa vào 1 câu query DB , lúc DB bị slow sẽ gây ra việc check không đúng, sinh ra việc trùng.

  • Giải pháp: Việc check dựa vào redis, sẽ nhanh và chính xác hơn, sửa lại thuật toán thành 1 vòng while tranh nhau barcode trong chuỗi mà không cần đợi nhau.

3. Lỗi duplicate request gây gửi mail trùng.

  • Bối cảnh: Khi thực hiện checkout thành công từ webview của APP, mail gửi order thành công tới user bị duplicate.

  • Nguyên nhân: Có một lỗi chưa xác định được là từ APP, hay từ hạ tầng, nhưng lại gửi duplicate request Request handle được viết ở controller chưa check trường hợp bị gọi nhiều lần

  • Solution: Nguyên cứu kĩ hơn các yếu tố đã gọi duplicate. Các function ở controller, đặc biệt là API, khi handle request nên tính đến yếu tố duplicate.

Ref: Idempotence - Wikipedia

4. Lỗi query elasticsearch dùng query script.

  • Bối cảnh:

    • Issue 1: Khi call API search ES, query sử dụng script dynamic ⇒ Vượt số lượng compile script ⇒ Search fail
    • Issue 2: Khi get list product, cần check điều kiện còn stock hay không, nhưng sau khi implement thêm script check stock => ES sometime quá tải => chết site
  • Nguyên nhân:

    • Issue 1: Vượt max_compilations_rate (default default 50/5m) do query sử dụng nhiều script
    • Issue 2: Data node của ES chỉ có thread pool search là 1000. Nhiều document product lại chứa khá nhiều location stock (max là 833). Script query trước đây loop qua mỗi item stock của product để check điều kiện còn stock => dẫn tới query chậm, hết pool => thi thoảng die query ES => chết site
  • Script query dùng cơ chế vòng for để check tất cả document, không sử dụng được index của các column trong ES

Performance: Script queries can be slower compared to queries written in the Query DSL. This is because scripts need to be dynamically compiled and executed at runtime, which incurs additional overhead. Query DSL can leverage various internal optimizations and caching mechanisms.

  • Script queries: Queries that need to do linear scans to identify matches.
  • By default, Elasticsearch indexes all data in every field and each indexed field has a dedicated, optimized data structure. For example, text fields are stored in inverted indices, and numeric and geo fields are stored in BKD trees. The ability to use the per-field data structures to assemble and return search results is what makes Elasticsearch so fast. (https://www.elastic.co/guide/en/elasticsearch/reference/current/documents-indices.htm)

Trước:

Sau:

  • Giải pháp:

Nâng max_compilations_rate lên 1000/1m Thay vì dùng script dynamic thì sử store script (register script với ES) Nâng spec ES từ 2 node lên 4 node + setting replica. Chuyển qua query DSL. Query DSL: Tận dụng được việc các column đã được index đầy đủ, việc check điều kiện stock diễn ra nhanh hơn. Thay vì script query sẽ không dùng được index.

5. Lỗi API nhưng lại set session, gây ra tràn memory redis.

  • Bối cảnh: Sau khi release APP, memory redis tăng từ từ lên 99.9%, redis gần như tràn memory

  • Nguyên nhân:

API dùng session để lưu access token cho việc giao tiếp giữa lớp authenticator và controller. Nhưng API lại không sử dụng cookie, nên mỗi lần request là tạo thêm session key trong redis => tràn memory

  • Solution: Loại bỏ việc dùng session trong các API

6. ECCUBE không chuyển query sang node read

  • Bối cảnh: 99% query được dùng trên node WRITE, rất ít dùng trên node READ

  • Nguyên nhân:

Trong ECCUBE, tất cả request được wrap trong 1 câu transaction của query DB, dù request đó chỉ toàn query READ Đối với doctrine2, các query được viết trong 1 transaction default sẽ được chuyển sang node WRITE

  • Solution: Viết class custom cho MasterSlaveConnection, thêm method lock() và forceConnect() để bắt buộc chọn connection READ.

(https://viblo.asia/p/symfony-4-eccube-lam-the-nao-de-luan-chuyen-query-giua-cac-node-master-slave-W13VMeGdVY7)

Kết:

Trên đây là những issue mình đã gặp trong giai đoạn release vừa qua, nhiều vấn đề không mới, nhưng dễ quên trong việc check. Hy vọng sẽ giúp ích cho mọi người trong thời gian tới 😀

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tạo console với Symfony

Giới thiệu. Tương tự như command artisan Laravel trong Symfony chúng ta có thể tạo ra các command để thực hiện các nghiệp vụ mà chúng ta mong muốn, ví dụ như chúng ta cần update nhiều records hay export csv ... mà không cần đến request của client thay vào đó chúng ta sẽ run CLI (commant line). . Upd

0 0 8

- vừa được xem lúc

[Symfony 4] Ẩn một số log không cần thiết với custom handler

Bối cảnh. Symfony phát sinh khá nhiều log như, như process init, begin transaction, ini, .

0 0 10

- vừa được xem lúc

[Symfony4] Giải thích cơ chế hoạt động của worker

Phạm vi sử dụng. Symfony là framework gạo cội trong làng PHP, với khá nhiều project xử dụng và custom.

0 0 9

- vừa được xem lúc

Symfony 4 + ECCUBE , làm thế nào để luân chuyển query giữa các node master slave

Mở đầu. Hắn nhiều người trong chúng ta có biết qua master slave node trong RDS , mặc định các framework PHP nổi tiếng như PHP , Symfony đều có hỗ trợ config master slave endpoint, để việc luân chuyển

0 0 17

- vừa được xem lúc

Tối ưu SQL - Join - Where (Phần 1)

Đây là vấn đề mình gặp trong quá trình làm việc, viết vào đây vừa để note lại cho bản thân, vừa chia sẻ với mọi người. users(id, name), 10tr bản ghi.

0 0 34

- vừa được xem lúc

Tối ưu SQL - Subqueries Count Distinct (Phần 2)

Tiếp theo bài 1 về tối ưu performance. . dashboards(id, name). .

0 0 31