October 5, 2011

APC - PHP Opcode Caching


Hôm nay, mình giới thiệu tới các bạn một kỹ thuật rất phổ biến khi làm việc với PHP nhưng cũng còn nhiều người chưa biết. Đã là dân lập trình, hẳn không ai trong chúng ta chưa từng nghe qua 2 cụm từ: "Biên dịch" và "Thông dịch". Và hầu như ai cũng biết là các chương trình dạng "biên dịch" sẽ chạy nhanh hơn so với các chương trình dạng "thông dịch", nhưng tại sao nó lại như vậy và có cách nào để cải thiện vấn đề này không. Bài viết sau, nhằm mục đích chia sẽ tới mọi người rõ hơn vì sao "thông dịch" chậm hơn "biên dịch" và 1 giải pháp giúp cải thiện đó là APC - Alternative PHP Caching

Hình 1: Object PHP Lifecycle. Như chúng ta thấy trong hình trên, mỗi request đến file PHP sẽ được tiến hành xử lý thông qua 4 bước trước khi trả kết quả về cho người dùng. Quá trình này là cần thiết cho việc thực thi lệnh lần đầu, nhưng thực sự không cần thiết cho những lần gọi sau đó, vì quá trình vẫn thực hiện đầy đủ 4 bước, dù file PHP không hề có sự thay đổi. Điều này chính là nguyên nhân chính dẫn tới việc "Thông dịch" chậm hơn nhiều so với "Biên dịch".

Hình 2: Object PHP Lifecycle after Caching. Sau khi được cache lại, quá trình thực hiện chỉ còn thông qua 2 bước là quét dữ liệu từ cache và thực thi lệnh. Như vậy nhanh hơn rất nhiều so với trước đó. Và theo đó, trong lần thực thi đầu tiên, ngoài việc chạy 4 bước như trên, thì code sẽ được lưu thêm vào cache để tăng tốc cho lần sau. Cái này gọi là lỗ trước, lời sau, mà lần sau thì lời to mà ^^

APC - Alternative PHP Caching - Opcode Caching Tool
1 - Giới thiệu:
APC là một FREE PHP Extension, là một công cụ hỗ trợ opcode caching rất đơn giản và cũng không kém phần hiệu quả. Ngoài ra, APC còn có thể dùng cho việc data caching.

2 - Cài đặt
APC có phiên bản dành cho Windows lẫn cho Linux. Tuy nhiên, vì blog của mình chủ yếu nói trên Linux, nên mình cũng chỉ tập trung cho cài đặt cho Linux.
Bạn thực hiện lần lượt các câu lệnh sau để tiến hành cài đặt APC vào LAMP Server
yum install php-pear
yum install httpd-devel
yum install pcre-devel
cd /usr/src
wget http://pecl.php.net/get/APC-3.1.9.tgz
tar -xvzf APC-3.1.9.tgz
cd APC-3.1.9
phpize
./configure --enable-apc --enable-apc-mmap --with-apxs --with-php-config=/usr/bin/php-config
make
make install

3 - Cấu hình APC cho PHP
gedit /etc/php.ini
Thêm các dòng sau vào cuối file
[APC]
extension = apc.so
apc.enabled = 1
apc.shm_size = 32
apc.ttl = 7200
apc.user_ttl = 7200
Sau đó restart lại Apache
/etc/init.d/httpd restart
Vậy là xong, quá trình cài đặt cho APC Opcode Caching hoàn tất.

4 - APC Admin
Copy file apc.php từ thư mục gốc vào thư mục chạy web, ví dụ như sau:
mkdir /var/www/html/apcadmin
cp apc.php /var/www/html/apcadmin/index.php
gedit /var/www/html/apcadmin/index.php
Sửa dòng sau:
defaults('ADMIN_PASSWORD','password');
Thành
defaults('ADMIN_PASSWORD','123456'); // Có thể thay bằng password khác, nhưng phải khác giá trị ban đầu
Sau đó vào trình duyệt, nhập vào url: http://localhost/apcadmin để vào trang admin của APC

5 - Disable APC cho PhpMyAdmin
gedit /etc/httpd/conf/httpd.conf
Copy dán đoạn sau vào cuối file
<Directory /var/www/html/phpmyadmin>
       Options Indexes FollowSymLinks MultiViews
       AllowOverride None
       Order allow,deny
       allow from all
       php_flag apc.cache_by_default Off
</Directory>
Sau đó restart lại Apache server
/etc/init.d/httpd restart
Như vậy là hoàn tất mọi thao tác cài đặt, cấu hình APC cho PHP để opcode caching. Thao tác caching sẽ tự động mà chúng ta không cần tác động gì thêm.
Hy vọng bài viết giúp mọi người thành công

XCache - Opcode Cache dành cho PHP
Memcached - Data PHP Caching

26 comments:

  1. Nói rõ hơn cho mọi người nắm phần này, vì mình vừa nhận được 1 contact cho rằng việc cache này nằm tại HDD.
    APC là một cơ chế cache ngay trên RAM chúng ta, nếu ai đã từng đọc và làm thử thì ắt sẽ biết khi vào giao diện quản lý của APC, sẽ có từng thống kê rất rõ của Memory hay nói chính xác hơn là RAM
    Và bên trên mình có 1 dòng như thế này, ai chịu khó tìm hiểu sẽ thấy ngay cái này có ý nghĩa gì, nhưng giờ mình nói luôn cho những ai không biết. "apc.shm_size = 32"
    Câu này có nghĩa là APC sẽ dùng 32MB RAM hệ thống để làm shared memory cho phần cache mà APC nắm giữ. Điều này cũng cho thấy APC không hề lưu trên HDD, vì lưu HDD mà lưu 32MB thì "xem thường HDD quá". Nó rõ thêm 1 tí nữa là APC không chỉ làm đc Opcache Code mà còn Data Cache nên 32MB này là dùng chung nếu chúng ta sử dụng cả 2 tính năng cho APC.
    Bạn nào đọc mà ko hiểu thì để lại comment trên blog, đừng contact trực tiếp vì biết đâu câu hỏi của bạn chính là câu hỏi của 1 người nào đó đang cần. Mình cũng chỉ đang tìm tòi, nên có thể mình không giải đáp gì đc nhiều, nhưng nếu chúng ta cùng bàn luận, vấn đề ắt hẳn sẽ được giải quyết nhanh hơn, rõ ràng hơn.
    Chúc các bạn cuối tuần vui vẻ.

    ReplyDelete
  2. Chia sẻ của bạn rất hay

    ReplyDelete
  3. tình hình là mình cũng đã cài rồi nhưng khi chạy apc.php thì chỉ có mình file apc.php là được cache còn những cái của drupal thì hoàn toàn không cache

    ReplyDelete
  4. Bạn Minh Bảo cho mình hỏi là bạn cũng cài đặt theo như bài viết của mình luôn phải không? Nếu vậy, bạn hãy xem thử file php.ini xem đã enable cái APC lên chưa, thứ 2 nữa bạn xem file http.conf xem có dùng flag của APC tắt chỗ nào không. Xem kỹ file http.conf nha bạn.
    Thanks bạn đã chia sẻ.

    ReplyDelete
  5. Zậy em chạy website trên gói hosting thì em có cách nào cải tiến tốc độ site dựa vào cách này không? Em là quản trị nên mù mấy cái này, xin được giúp.

    ReplyDelete
  6. Theo như anh biết thì hầu hết các hosting server đều có cái sẵn cái này rồi, nên em yên tâm ha.
    Cám ơn em đã ghé thăm blog và để lại lời nhắn.

    ReplyDelete
  7. bạn có thể nói qua về caching cho data được ko

    ReplyDelete
  8. Chào bạn,
    Vấn đề caching data dùng APC rất đơn giản. Bạn chỉ việc dùng các function của nó là xong. Bạn tham khảo thêm tại link sau:
    http://www.php.net/manual/en/ref.apc.php

    ReplyDelete
  9. Theo mình hiểu thì APC có 2 phần:
    1 là tạo opcode tức là mã PHP đã biên dịch để chạy nhanh hơn.
    2 là cache data theo dạng key-value như Memcached, Redis.
    -----------------------------------------------------------------------------
    Tính năng thứ nhất thì ngoài APC còn có XCache nhưng có lẽ APC tốt hơn nhiều.
    Còn tính năng thứ 2 thì APC có tốt hơn được Memcached không bạn? Mình mới tìm hiểu các giải pháp tối ưu PHP trong buổi chiều này nên chưa biết gì nhiều. Có gì sai mọi người cứ góp ý thẳng.

    ReplyDelete
  10. Rất cảm ơn bạn đã có sự đóng góp tại đây. Mình xin chia sẻ một ít kinh nghiệm mà mình biết được như sau:
    1 - Đúng như bạn nói và bên trên mình cũng có nói. APC vừa làm opcode cache vừa làm data cache. XCache cũng làm được điều tương tự như APC luôn bạn.
    2 - APC và XCache cái nào tốt hơn cái nào, mình cũng có chia sẻ một link so sánh giữa 2 cái với nhau. Bạn có thể tham khảo thêm.
    3 - APC hay XCache khi dùng làm data cache thì chỉ dùng trên 1 server. Tức là nếu bạn có nhiều server cache thì các cache trên từng server là độc lập nếu dùng APC hay XCache. Tuy nhiên, Memcached hỗ trợ tính năng multi cho bạn. Và nếu so sánh performance, memcached là lựa chọn hàng đầu đó bạn.
    Rất cảm ơn bạn quan tâm.

    ReplyDelete
  11. Cám ơn bài viết của bạn chủ, nó rất có ích cho mình :)
    Mình có 1 thắc mắc muốn nhờ bạn giải đáp giúp: khi mình cài apc (php_apc.dll) thì báo lỗi như sau:

    PHP Startup: apc: Unable to initialize module
    Module compiled with module API=20090626
    PHP compiled with module API=20100525
    These options need to match

    Lỗi này như thế nào, ảnh hưởng ra sao, có phải giải quyết gì không? mong bác chủ giúp mình câu hỏi này (mình dùng windows!)

    ReplyDelete
  12. Rất cảm ơn bạn để lại tin nhắn. Rất tiếc là mình không làm việc trên windows nên cũng không rành vấn đề này lắm.
    Bạn thử google xem.

    ReplyDelete
  13. Em cũng cài như hướng dẫn của anh nhưng không được, và em cai như trong bài này (http://www.howtoforge.com/apc-php5-apache2-debian-etch) nó không báo lỗi gì nhưng chạy phpinfo() thì không thấy có APC.
    Em gõ php -v thì chỉ có thế này:
    -----------------------
    PHP 5.3.10-1ubuntu3.7 with Suhosin-Patch (cli) (built: Jul 15 2013 18:10:56)
    Copyright (c) 1997-2012 The PHP Group
    Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies

    -----------------------
    Mong anh chỉ giúp.
    Cảm ơn anh !

    ReplyDelete
  14. Hi em,

    Nếu em đã dùng Ubuntu thì tạm thời cứ đơn giản mọi chuyện trước. Dùng lệnh sau để cài em nha:

    "sudo apt-get install php-apc"

    Cách anh làm bên trên build từ source nên cũng có đôi khi hợi khó khi mới tiếp cận.

    Cám ơn em đã để lại lời nhắn

    ReplyDelete
  15. Cảm ơn anh đã trả lời. Em cũng đã cài nhiều cách rồi mà vẫn không thành công.
    Em đang dùng PHP 5.4.16 nên có thể đây cũng là nguyên nhân :(
    http://stackoverflow.com/questions/9611676/is-apc-compatible-with-php-5-4-or-php-5-5/9676164#9676164
    Cũng đã cài bằng SVN nó báo thành công nhưng chay phpinfo() thì cũng ko thấy đâu :(

    ReplyDelete
  16. Chào em,

    Anh cũng dùng Ubuntu 12.04, PHP 5.5 tự build và không còn dùng APC nữa vì PHP 5.5 có cái opcache mạnh hơn APC.

    Thân,

    ReplyDelete
  17. Chào bạn!

    Hiện tại mình dùng VPS 1GB, dùng APC cached nhưng thấy rất tốn tài nguyên của RAM.
    VPS mình dùng SSD, nên mình cần tìm 1 tool cache trên SSD (Disk) chứ không phải RAM như APC.

    Bạn giúp mình với nhé

    Thanks

    ReplyDelete
  18. Chào bạn John,

    Theo như mình biết thì việc opcode cache PHP đến hiện nay vẫn chỉ có cache trên RAM, chưa có cache trên SSD/HDD. Nếu muốn xây 1 website tốt, có sự phát triển mạnh, high performance thì mình nghĩ việc đầu tư cho RAM thì không có gì phải đắng đo bạn nhỉ.
    Dù SSD đã nhanh hơn rất nhiều so với HDD nhưng so với RAM thì nó vẫn chậm hơn đáng kể.

    Cảm ơn bạn đã để lại tin nhắn.

    ReplyDelete
  19. a có thể gửi cho e một ví dụ cụ thể về apc caching.

    ReplyDelete
    Replies
    1. APC chỉ đơn giản là vậy, còn ví dụ cụ thể thì tùy ứng dụng thôi. Nó cấu hình thôi chứ đâu có làm gì đâu

      Delete
  20. Mình đang quan tâm vấn đề giấu source code php. Mình định là dùng APC này để comply code thành binary rồi add vào cache. Còn trên các file web thì mình không include từ file.php mà include từ APC cache, như vậy có được không bạn? Mình không rành cái này lắm, có gì xin bạn chỉ giúp. Thanks bạn.

    ReplyDelete
    Replies
    1. Thắc mắc này của bạn mình ko nói sâu gì cả, chỉ hỏi bạn 1 vấn đề là bạn đã nghĩ đến trường hợp miss cache hay chưa khi nghĩ tới giải pháp này.
      Cache là một temporary storage, tức là chỉ mang tính chất lưu trữ tạm thời, nó sẽ mất trong rất nhiều trường hợp (reboot server, clear cache, expried ...) như vậy thì cách này đã không hiệu quả.
      Nếu bạn muốn giấu code của bạn, bạn đầu tư hẳn 1 con server cho bạn là ok hết thôi

      Delete
    2. Hi anh Minh. Cái vấn đề cache biên dịch như sử dụng thư viện APC này nó ảnh hưởng gì đến việc dữ liệu thay đổi không ạ, có cần thiết phải xóa cache mỗi khi thay đổi(Cập nhật db, ...) k ạ?

      Delete
    3. Hi em,

      Trước hết cảm ơn em quan tâm blog anh.

      1- Dùng cache là 1 chỗ dữ liệu được lưu trữ dư thêm, nhẳm hạn chế tần suất quét xuống DB. Nên nếu em làm bài bản từ phần code ánh xạ xuống DB + Cache thì dĩ nhiên em handle đc rồi. Tức là khi có update/delete data trong DB thì em mần luôn trong cache

      2 - Nếu trường hợp nhúng tay trực tiếp vào sửa DB thì dĩ nhiên không qua code để handle cache => phải clear key cache cần thiết để nó chương trình có thể "nạp" lại khi bị mất (cái này em phải làm trong code)

      3 - Hiện tại APC đã chuyển thành APCu nếu em muốn dùng APC cho việc caching

      p/s: anh tên Quang chứ ko phải tên Minh ^_^

      Delete
  21. Cho mình hỏi APC với APCu nó khác nhau gì? Bạn có thể nói rõ hơn được không? Cảm ơn bạn rất nhiều.

    ReplyDelete
    Replies
    1. Chào bạn, thật xin lỗi vì mấy tháng nay mình có một dự án khác thật hiện nên không check blog như trước. APCu là dự án phát triển từ APC. Mục đích APC là opcode cache và data cache. Nhưng sau khi PHP 5.5 ra đời, với cơ chế opcache code từ Zend Optimizer+ tốt hơn và chính hãng hơn APC nên APC ko còn đất sống trong việc opcode cache nữa. Nhưng nó không chết hẳn, vì nó còn phần data cache, nên mới sinh ra cái APCu, chữ "u" là user ý nói là cache data do user push vào.

      Delete