Giới Thiệu Về Memcached

Nguyễn Đạt

Hai người bạn tên là Programmer và Sysadmin cùng đi trên một hành trình và nhiệm vụ của họ là xây dựng một website sử dụng PHP và cơ sở dữ liệu MySQL. Khi người dùng từ khắp nơi trên thế giới truy cập website, họ gửi request tới Apache Webserver và Apache truy vấn cơ sở dữ liệu MySQL để lấy dữ liệu trả về cho người dùng. Khi số lượng truy cập tăng lên, Programmer lập trình để tạo ứng dụng còn Sysadmin quản lý và vận hành máy chủ Apache server và máy chủ database MySQL.

Một ngày nọ, Sysadmin nhận ra webserver của họ gặp phải vấn đề về chịu tải khi có quá nhiều truy cập gửi tới Apache và MySQL server phải xử lý một lượng lớn dữ liệu trong thời gian ngắn. Thời gian để hoàn thành việc xử lý mỗi request lên tới 5 giây và với tốc độ như vậy thì người dùng cảm thấy rất khó chịu khi phải đợi trang lâu thì trang web mới load xong. Lúc này Programmer mới nói với Sysadmin: "Giờ phải làm gì để tăng tốc độ load website". Sys nghe xong trả lời "Tao mới nghe nói Memcached có thể xử lý rất tốt việc việc này". "Ok vậy thì hãy thử Mencached" - Programmer trả lời.

Sysadmin nhận thấy có tất cả 6 webserver đang hoạt động và anh ta quyết định sử dụng 3 trong số đó để chạy Memcached. Sysadmin thêm vào 1 GB dung lượng RAM cho mỗi webserver trong số 3 số được chọn và khởi động Memcached với giới hạn bộ nhớ là 1GB. Như vậy hiện tại có tất cả 3 Memcached instance đang chạy trên 3 server và mỗi trong số đó có thể chứa tới tối đa 1GB dữ liệu. Tuy nhiên việc thêm Memcached này cũng vẫn chưa thể phát huy hiệu quả mà thậm chí còn làm nặng thêm server.

Lúc này trong source code của ứng dụng, Programmer tạo một mảng chứa địa chỉ IP của 3 server Memcached như sau:

$MEMCACHE_SERVERS = array(
    "10.1.1.1", //web1
    "10.1.1.2", //web2
    "10.1.1.3", //web3
);

Và với thư viện Memcache đã được cài trên cả 6 webserver này, Programmer bây giờ có thể tạo một object từ thư viện này:

$memcache = new Memcache();

Và thêm mỗi server trong 3 servers vào object $memcache mới tạo ra:

foreach($MEMCACHE_SERVERS as $server){
    $memcache->addServer ( $server );
}

Sau đó, Programmer nhận thấy trong mã lệnh của ứng dụng có một câu truy vấn tới database như sau:

SELECT * FROM big_table WHERE timestamp > last_week ORDER BY timestamp ASC LIMIT 50000; 

Và MySQL database cần tới 5 giây để xử lý xong câu truy vấn trên. Vì vậy Programmer nghĩ nên đưa kết quả của câu truy vấn trên vào trong Memcached. Để làm việc này một cách hiệu quả nhất, ứng dụng sẽ trước tiên kiểm tra trong Memcached xem đã có kết quả nào của câu truy vấn trên được lưu trong cache chưa? Nếu chưa có cache nào được lưu thì ứng dụng sẽ truy vấn MySQL và lưu kết quả trả về vào cache. Ngược lại nếu lưu rồi thì chúng ta sẽ sử dụng dữ liệu được lưu trong cache. Và như vậy, Programmer lúc này cập nhật source code trong ứng dụng như sau:

$huge_data_for_front_page = $memcache->get("huge_data_for_front_page");
if($huge_data_for_front_page === false){
    $huge_data_for_front_page = array();
    $sql = "SELECT * FROM hugetable WHERE timestamp > lastweek ORDER BY timestamp ASC LIMIT 50000";
    $res = mysql_query($sql, $mysql_connection);
    while($rec = mysql_fetch_assoc($res)){
        $huge_data_for_front_page[] = $rec;
    }
    // cache for 10 minutes
    $memcache->set("huge_data_for_front_page", $huge_data_for_front_page, 0, 600);
}

// use $huge_data_for_front_page how you please

Và sau khi đẩy source code mới được cập nhật lên server, thời gian tải dữ liệu giờ đã giảm đáng kể!

Thêm Phản Hồi

Bài Viết Liên Quan