NHANWEB

Sử dụng memcache với PHP và MySQL

Memcachemột công cụ tạo bộ nhớ đệm gần như tốt nhất cho rất nhiều mã nguồn mở cũng như môi trường lập trình. Sử dụng caching, bạn có thể nâng cao tốc độ xử lý của website(hoặc ứng dụng web) bằng cách giảm thiểu số lượng request tới cơ sở dữ liệu – một trong những request hao tốn tài nguyên hệ thống nhiều nhất. Vấn đề là làm thế nào để đưa memcache vào một dự án một cách dễ dàng và không làm ảnh hưởng nhiều đến mã lập trình đã có sẵn ?

Sử dụng caching hệ thống của bạn có thể hoạt động nhanh hơn

Từ khi memcache được xây dựng như một đối tượng (OBJECT caching system), bạn chỉ cần thả thông tin nhận được sau khi thực hiện mysql_query vào memcache; những lần sử dụng nguồn tài nguyên này sau đó bạn có thể lấy thông tin từ memcache để sử dụng thay vì phải sử dụng mysql_query thêm nữa. Đây là khái niệm đầu tiên mà tôi(hoặc bạn) nên biết nếu lần đầu tiếp xúc với memcache. Một tin tốt lành cho bạn là memcache có thể lưu được nhiều kiểu dữ liệu khác nhau như String, Integer, Float, Array …

Dưới đây là một vài thứ tôi học được trong quá trình sử dụng memcache:

  1. Memcache là ưu tiên tốt nhất khi lưu trữ những truy vấn chậm nhưng trả lại dữ liệu nhỏ (1 đến 50 record) tùy thuộc vào kích thước dữ liệu.
  2. Memcache không phải là lựa chọn sáng suốt đối với những truy vấn trả về số lượng dữ liệu lớn (hơn 100 record cho truy vấn)

Tuy nhiên, trong thực tế, đôi lúc tôi nhận thấy rằng sử dụng memcache có khi không nhanh bằng truy vấn trực tiếp vào database(DB), điều này càng rõ ràng hơn nếu như bạn có một máy chủ khỏe và khả năng truy vấn DB tốt. Tất cả nằm ở những gì bạn có: máy chủ, mã lập trình, câu query…Bạn cần kiểm tra và quyết định nên sử dụng hoặc không nên sử dụng memcache tùy vào thực tế.

– Nếu Cache giúp cho hệ thống nhanh hơn ! Hãy sử dụng nó.
– Nếu database query nhanh hơn ! Bạn không nên sử dụng memcache.

Về căn bản, bạn có thể kết hợp tùy từng tình huống cụ thể để sử dụng hoặc không sử dụng memcache.

Dưới đây là code tôi sử dụng để “cache” query:

[code language=”php”]

<?php
# Connect to memcache:
global $memcache;
$memcache = new Memcache;

# Gets key / value pair into memcache … called by mysql_query_cache()
function getCache($key) {
global $memcache;
return ($memcache) ? $memcache->get($key) : false;
}

# Puts key / value pair into memcache … called by mysql_query_cache()
function setCache($key,$object,$timeout = 60) {
global $memcache;
return ($memcache) ? $memcache->set($key,$object,MEMCACHE_COMPRESSED,$timeout) : false;
}

# Caching version of mysql_query()
function mysql_query_cache($sql,$linkIdentifier = false,$timeout = 60) {
if (($cache = getCache(md5("mysql_query" . $sql))) !== false) {
$cache = false;
$r = ($linkIdentifier !== false) ? mysql_query($sql,$linkIdentifier) : mysql_query($sql);
if (is_resource($r) && (($rows = mysql_num_rows($r)) !== 0)) {
for ($i=0;$i<$rows;$i++) {
$fields = mysql_num_fields($r);
$row = mysql_fetch_array($r);
for ($j=0;$j<$fields;$j++) {
if ($i === 0) {
$columns[$j] = mysql_field_name($r,$j);
}
$cache[$i][$columns[$j]] = $row[$j];
}
}
if (!setCache(md5("mysql_query" . $sql),$cache,$timeout)) {
# If we get here, there isn’t a memcache daemon running or responding
}
}
}
return $cache;
}
?>
[/code]

Như bạn đã thấy, hàm mysql_query_cache() sẽ trả về một mảng chứa kết quả của truy vấn. Vì lượng dữ liệu tương đối nhỏ(như tôi đã nói ở trên) nên tôi không sử dụng mysql_free_result() để giải phóng vùng nhớ. Nếu dữ liệu của bạn nhiều hơn, bạn có thể sử dụng mysql_free_result() để giải phóng vùng nhớ.

Sử dụng đoạn code trên như sau:

[code language=”php”] <?php
$sql = "
SELECT `dataID`, `dataTitle`
FROM `tbldata`
WHERE `dataTypeID` BETWEEN 2 AND 2093
AND `dataStatusID` IN (1,2,3,4)
AND `dataTitle` LIKE ‘%something%’
ORDER BY `dataDate` DESC
LIMIT 10
";

# Before: [without memcache] $rSlowQuery = mysql_query($sql);
# $rSlowQuery is a MySQL resource
$rows = mysql_num_rows($rSlowQuery);
for ($i=0;$i<$rows;$i++) {
$dataID = intval(mysql_result($rSlowQuery,$i,"dataID"));
$dataTitle = mysql_result($rSlowQuery,$i,"dataTitle");

echo "<a href=\"/somewhere/$dataID\">$dataTitle</a><br />\n";
}

# After: [with memcache] $rSlowQuery = mysql_query_cache($sql);
# $rSlowQuery is an array
$rows = count($rSlowQuery);
for ($i=0;$i<$rows;$i++) {
$dataID = intval($rSlowQuery[$i]["dataID"]);
$dataTitle = $rSlowQuery[$i]["dataTitle"];

echo "<a href=\"/somewhere/$dataID\">$dataTitle</a><br />\n";
[/code]

Đó là những gì tôi muốn chia sẻ cũng các bạn, bạn có thể sử dụng đoạn code trên hoặc thấy nó chưa thực sự tốt, chưa thực sự tối ưu. Vui lòng để lại 1 bình luận nhé.

Exit mobile version