如何在 Ubuntu 14.04 上安装和使用 Memcache

介绍

随着您的网站的增长和流量增加,显示压力最快的组件之一是后端数据库. 如果您的数据库没有分布和配置来处理高负载,它可以很容易被相对较小的流量增加所压倒。

解决此问题的一种方法是利用一个内存对象缓存系统,如 memcached . Memcached 是一种缓存系统,通过在内存中暂时存储通常会从数据库中获取的信息而起作用。

在本指南中,我们将讨论如何在Ubuntu 14.04服务器上安装和使用memcached。

前提条件

在我们开始之前,您应该在您的服务器上有一个常规的非根用户,可以访问sudo特权. 如果您还没有创建过这样的用户,您可以按照我们的 Ubuntu 14.04 初始设置指南中的步骤 1 到 4 这样做。

当您的常规用户已配置时,请继续使用本指南。

安装 Memcached 和组件

要开始,我们应该从Ubuntu的存储库中获得我们所需要的所有组件,幸运的是,我们所需要的一切都可用。

由于这是我们本会中的第一个apt操作,我们应该更新我们的本地包索引,然后我们可以安装我们的程序。

我们将安装 memcached 以及 MySQL 数据库后端和 PHP 来处理交互。我们还安装了处理 memcached 交互的 PHP 扩展。

1sudo apt-get update
2sudo apt-get install mysql-server php5-mysql php5 php5-memcached memcached

请注意,有两个 PHP memcache 扩展,一个叫做php5-memcache,另一个叫做php5-memcached(在第二个例子中请注意后续的d)。

如果您尚未安装 MySQL,安装将提示您选择并确认管理员的密码。

这应该安装和配置你需要的一切。

检查安装

相信它或不相信, memcached 已经完全安装并准备好运行,我们可以通过多种不同的方式来测试它。

第一种方法很简单,我们可以问PHP是否知道我们的memcached扩展以及是否已启用,我们可以通过创建无处不在的PHP信息页来做到这一点。

在Ubuntu 14.04上的Apache中,我们的默认文档根是 /var/www/html

1sudo nano /var/www/html/info.php

在此文件中,输入这个,这基本上只是调用一个PHP函数,该函数收集并将我们服务器的信息打印成一个易于浏览的布局。

1<?php
2phpinfo();
3?>

现在,你可以访问你的服务器的域名或公共IP地址,然后是/info.php,你应该看到一个信息页面。

http://server_domain_name_or_IP/info.php

如果您向下滚动或搜索memcached部分标题,您应该找到一些看起来像这样的东西:

Memcache PHP info section

这意味着 memcached 扩展已启用并由 Web 服务器找到。

我们还可以通过键入检查 memcached 服务是否正在运行:

1ps aux | grep memcached

1memcache 6584 0.0 0.0 327448 3004 ?        Sl 14:07 0:00 /usr/bin/memcached -m 64 -p 11211 -u memcache -l 127.0.0.1
2demouser 6636 0.0 0.0 11744 904 pts/0 S+   14:29 0:00 grep --color=auto memcached

您可以通过键入查询服务的统计数据:

1echo "stats settings" | nc localhost 11211

如果您需要停止、启动或重新启动 memcached 服务,您可以通过键入以下内容来完成此操作:

sudo service memcached restart

测试 Memcached 是否可以缓存数据

现在我们已经验证了 memcached 正在运行,并且我们的 PHP 扩展已启用以连接到它,我们可以尝试让它存储数据。

我们将通过创建另一个PHP脚本来做到这一点,这一次,它将更加复杂。

在我们的文档根中打开名为cache_test.php的文件:

1sudo nano /var/www/html/cache_test.php

内部,开始创建PHP包装标签:

<?php
?>

在这些中,我们将创建一个新的PHP Memcached对象实例,并将其存储在一个变量中。我们将定义这个PHP对象可以连接到我们服务器上运行的实际 memcached服务的位置。

<?php
$mem = new Memcached();
$mem->addServer("127.0.0.1", 11211);
?>

接下来,我们会告诉我们的 Memcached 实例从我们的缓存中查询一个密钥. 这个密钥可以被称为任何东西,因为我们还没有创建它。

<?php
$mem = new Memcached();
$mem->addServer("127.0.0.1", 11211);

$result = $mem->get("blah");
?>

接下来,我们只需要测试是否返回了任何东西。如果 memcached 找到一个名为blah的密钥,我们希望它打印与该密钥相关的值。

然后我们应该将密钥设置为一个值,以便下次我们询问该值时,memcached 会找到我们给它的值:

<?php
$mem = new Memcached();
$mem->addServer("127.0.0.1", 11211);

$result = $mem->get("blah");

if ($result) {
    echo $result;
} else {
    echo "No matching key found. I'll add that now!";
    $mem->set("blah", "I am data!  I am held in memcached!") or die("Couldn't save anything to memcached...");
}
?>

如果我们访问这个页面在我们的网页浏览器,我们可以看到这是如何工作的:

http://server_domain_name_or_IP/cache_test.php

首先,你应该看到一个看起来像这样的页面:

Memcached uncached message

但是,如果我们更新页面,我们应该看到另一个信息:

Memcached cached message

正如你所看到的,我们的 memcached 服务现在正在缓存我们脚本设置的数据。

测试临时缓存数据库值

现在我们已经测试了在 memcached 中存储数据的能力,我们可以展示一个更现实的场景:暂时从数据库查询中缓存结果。

在MySQL中创建样本数据

要做到这一点,我们首先需要在我们的数据库中存储一些信息。

您将需要输入您在安装过程中设置的 MySQL 根密码:

1mysql -u root -p

之后,你会得到一个MySQL提示。

首先,我们要创建一个数据库来测试,然后选择数据库:

1CREATE DATABASE mem_test;
2USE mem_test;

让我们创建一个名为测试的用户,其密码是testing123,可以访问我们创建的数据库:

1GRANT ALL ON mem_test.* TO test@localhost IDENTIFIED BY 'testing123';

现在,我们将创建一个真正的基本表并插入一个记录,该表将被称为sample_data,它只会有一个索引和一个字符串字段:

1CREATE TABLE sample_data (id int, name varchar(30));
2INSERT INTO sample_data VALUES (1, "some_data");

现在,我们已经创建了我们的结构,并插入了数据,我们可以离开MySQL:

1exit

创建 PHP 脚本来缓存 MySQL 数据

现在我们在MySQL中有数据,我们可以创建另一个PHP脚本,以类似于生产PHP应用程序的方式运作。

它会搜索 memcached 中的数据,并在找到数据时返回它;如果没有找到数据,则会从数据库中进行查询,然后将结果存储在 memcached 中,以便在未来进行查询。

首先,在我们的文档根中创建另一个 PHP 脚本,我们将这个脚本称为 database_test.php:

1sudo nano /var/www/html/database_test.php

我们将创建一个 PHP memcached 实例,然后告诉它在我们的服务器上运行的 memcached 服务所在地,就像我们上次一样:

<?php
$mem = new Memcached();
$mem->addServer("127.0.0.1", 11211);
?>

接下来,在我们第一次离开我们最后的脚本时,我们将不得不定义PHP如何连接到我们的MySQL数据库,我们需要为我们创建的用户指定登录凭证,然后我们需要告诉它使用哪个数据库:

<?php
$mem = new Memcached();
$mem->addServer("127.0.0.1", 11211);

mysql_connect("localhost", "test", "testing123") or die(mysql_error());
mysql_select_db("mem_test") or die(mysql_error());
?>

接下来,我们将不得不设计我们需要提取我们插入到我们的表中的数据的查询,我们将将此存储在一个$ Query变量中。

然后,我们将创建一个$querykey变量来存储 memcached 将用于引用我们的信息的密钥。

我们使用字符串KEY创建此密钥,然后将查询的 md5 (一个哈希方法) 检查总数附加到尾声,以确保每一个密钥在较大的数据集上使用此技术时都是独一无二的。

<?php
$mem = new Memcached();
$mem->addServer("127.0.0.1", 11211);

mysql_connect("localhost", "test", "testing123") or die(mysql_error());
mysql_select_db("mem_test") or die(mysql_error());

$query = "SELECT ID FROM sample_data WHERE name = 'some_data'";
$querykey = "KEY" . md5($query);
?>

接下来,我们将创建一个$result变量,就像我们最后的脚本一样,这将保持我们 memcached 查询的结果,就像以前一样。

<?php
$mem = new Memcached();
$mem->addServer("127.0.0.1", 11211);

mysql_connect("localhost", "test", "testing123") or die(mysql_error());
mysql_select_db("mem_test") or die(mysql_error());

$query = "SELECT name FROM sample_data WHERE id = 1";
$querykey = "KEY" . md5($query);

$result = $mem->get($querykey);
?>

现在我们已经做好了实际测试逻辑的准备,以确定在 memcached 中找到结果时会发生什么。

<?php
$mem = new Memcached();
$mem->addServer("127.0.0.1", 11211);

mysql_connect("localhost", "test", "testing123") or die(mysql_error());
mysql_select_db("mem_test") or die(mysql_error());

$query = "SELECT name FROM sample_data WHERE id = 1";
$querykey = "KEY" . md5($query);

$result = $mem->get($querykey);

if ($result) {
    print "<p>Data was: " . $result[0] . "</p>";
    print "<p>Caching success!</p><p>Retrieved data from memcached!</p>";
}
?>

现在,让我们为替代场景添加逻辑。如果结果找不到,我们希望使用我们编写的查询来询问MySQL的数据。

在我们有查询结果后,我们需要将该结果添加到 memcached,以便下次我们这样做时数据会存在。

我们会将我们的内容缓存10秒。在现实世界中,缓存内容更长的时间很可能是有益的。如果您的内容没有发生太大的变化,可能会更接近10分钟(600秒),所以我们可以更快地看到发生了什么,而不需要重新启动我们的 memcached 服务。

之后,我们会打印一个类似的消息,包含查询结果,并告诉用户发生了什么事,我们应该将整个块作为我们以前的如果else添加:

<?php
$mem = new Memcached();
$mem->addServer("127.0.0.1", 11211);

mysql_connect("localhost", "test", "testing123") or die(mysql_error());
mysql_select_db("mem_test") or die(mysql_error());

$query = "SELECT name FROM sample_data WHERE id = 1";
$querykey = "KEY" . md5($query);

$result = $mem->get($querykey);

if ($result) {
    print "<p>Data was: " . $result[0] . "</p>";
    print "<p>Caching success!</p><p>Retrieved data from memcached!</p>";
} else {
    $result = mysql_fetch_array(mysql_query($query)) or die(mysql_error());
    $mem->set($querykey, $result, 10);
    print "<p>Data was: " . $result[0] . "</p>";
    print "<p>Data not found in memcached.</p><p>Data retrieved from MySQL and stored in memcached for next time.</p>";
}
?>

这是我们完成的脚本,它会尝试从 memcached 获取数据并返回它. 如果没有,它会直接从 MySQL 查询并缓存结果 10 秒。

测试剧本

现在我们已经写了脚本,我们可以通过在我们的Web浏览器中访问我们的文件位置来运行它:

http://server_domain_name_or_IP/database_test.php

第一次访问页面时,我们应该看到这样的输出:

Memcached uncached database query

如果我们更新此信息(在上次访问后的10秒内),则该页面现在应该显示不同的信息:

Memcached cached database query

如果我们再等一会儿,缓存内容将过期并再次从 memcached 中删除,我们可以在此时更新以再次收到第一个消息,因为服务器必须返回数据库以获取相应的值。

结论

到目前为止,您应该了解 memcached 是如何工作的,以及如何利用它来防止您的 Web 服务器反复击中数据库以获取相同的内容。

虽然我们在本指南中创建的PHP脚本仅仅是示例,但它们应该为您提供系统工作方式的好主意,还应该为您提供如何构建代码的好主意,以便您可以检查 memcached 并在必要时返回数据库。

By Justin Ellingwood
Published At
Categories with 技术
comments powered by Disqus