作者选择了 Girls Who Code以作为 Write for Donations计划的一部分获得捐款。
介绍
Redis (Remote Dictionary Server)是一个快速的开源内存数据库,您可以使用它作为一个高度可扩展和性能导向的系统的关键价值存储。Redis的一些用例包括:缓存,高速交易,实时分析,实时通知,机器学习,搜索和队列/工作处理。
Caching是将数据暂时存储在高速存储层中(例如,在计算机的RAM中),以便在客户端提出相同的未来请求时更快地服务数据。
当您使用 PHP和 MySQL时,使用 Redis 作为缓存可以提高应用程序的性能,因为 Redis 会将数据存储在内存中,这比硬盘(HDD)或固态驱动器(SSD)快几倍。
缓存数据是一个不可或缺的设计功能,当您设计具有较高读数的Web应用程序时,这些应用程序包括博客,在线商店和社交媒体网站。
在本教程中,您将使用 Redis 在 Ubuntu 20.04 上使用 PHP 缓存 MySQL 数据。
前提条件
要完成本教程,您将需要以下内容:
- 具有 sudo 特权的非根用户的 Ubuntu 20.04 服务器. 按照 初始服务器设置与 Ubuntu 20.04] 指南设置此设置.
- 一个 LAMP 堆栈。 按照 [如何在 Ubuntu 20.04 上安装 Linux, Apache, MySQL, PHP (LAMP) 堆栈(https://andsky.com/tech/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu-20-04) 教程。 对于本指南,您可以跳过 步骤 4 — 为您的网站创建虚拟主机()
- 通过遵循 如何在 Ubuntu 20.04 上安装和保护 Redis - Quickstart 教程设置的 Redis 服务器。
步骤 1 — 安装PHP的Redis库
要开始,您将安装php-redis
扩展,这将允许您使用PHP与Redis进行通信。运行以下命令来更新您的服务器并安装扩展:
1sudo apt update
2sudo apt install php-redis
确认安装并重新启动 Apache Web 服务器来加载扩展:
1sudo systemctl restart apache2
现在你已经安装了你的依赖,你将设置你的数据库。
步骤 2 – 设置测试数据库、表和样本数据
在此步骤中,您将创建一个MySQL数据库,将数据永久存储在磁盘上,您还将创建一些表和用户帐户,对数据库具有完整的权限。
首先,登录您的MySQL服务器作为一个 root用户:
1sudo mysql -u root -p
输入您在 LAMP 前提条件中设置的 MySQL 服务器的 root 密码。
接下来,使用以下命令创建test_store
数据库:
1CREATE database test_store;
通过确认输出,确保操作成功:
1[secondary_label Output]
2Query OK, 1 row affected (0.00 sec)
接下来,为您的数据库创建一个用户,我们将在本教程中将这个用户称为 **test_user。
1CREATE USER 'test_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'PASSWORD';
然后向test_store
数据库授予完整的权限:
1GRANT ALL PRIVILEGES ON test_store.* TO 'test_user'@'localhost';
最后,运行以下命令,在MySQL中重新加载授权表:
1FLUSH PRIVILEGES;
确保您在每个成功命令后获得以下输出:
1[secondary_label Output]
2Query OK, 0 rows affected (0.01 sec)
结束 MySQL root 会话:
1quit;
您将收到再见
这个词,系统将带您回到服务器的命令行界面。
重新登录 MySQL 服务器,使用您刚刚创建的 test_user 凭证:
1mysql -u test_user -p
输入 test_user的密码,然后在mysql>
提示中切换到test_store
数据库:
1USE test_store;
确保您收到以下输出:
1[secondary_label Output]
2Database Changed.
接下来,您将创建一个包含三个列的产品
表。 您将使用product_id
列单独识别每个产品。 为了避免手动分配ID,您将使用AUTO_INCREMENT
关键字。 然后,您将使用BIGINT
数据类型用于product_id
列,以支持大数据集。
该产品名称
字段将包含您的项目的实际名称。在这种情况下,一个长度为50
字符的VARCHAR
数据类型(https://dev.mysql.com/doc/refman/8.0/en/char.html)就足够了。在产品
表中,最后一列是价格
――您将使用DOUBLE
数据类型(https://dev.mysql.com/doc/refman/8.0/en/numeric-types.html)来容纳数位数的价格(例如, 16.33)。
要创建产品
表,运行以下命令:
1CREATE table products
2(
3product_id BIGINT PRIMARY KEY AUTO_INCREMENT,
4product_name VARCHAR(50),
5price DOUBLE
6) Engine = InnoDB;
您将获得以下输出:
1[secondary_label Output]
2Query OK, 0 rows affected (0.01 sec)
现在,您将填充产品
表中一些记录用于测试目的。
您不需要手动输入product_id
列中的数据,因为AUTO_INCREMENT
列将完成此操作。
1INSERT INTO products(product_name, price) VALUES ('Virtual Private Servers', '5.00');
2INSERT INTO products(product_name, price) VALUES ('Managed Databases', '15.00');
3INSERT INTO products(product_name, price) VALUES ('Block Storage', '10.00');
4INSERT INTO products(product_name, price) VALUES ('Managed Kubernetes', '60.00');
5INSERT INTO products(product_name, price) VALUES ('Load Balancer', '10.00');
运行每个命令后,确保您获得此输出:
1[secondary_label Output]
2Query OK, 1 row affected (0.00 sec)
使用SELECT
命令验证数据:
1SELECT * FROM products;
您将收到类似于以下的输出:
1[secondary_label Output]
2+------------+-------------------------+-------+
3| product_id | product_name | price |
4+------------+-------------------------+-------+
5| 1 | Virtual Private Servers | 5 |
6| 2 | Managed Databases | 15 |
7| 3 | Block Storage | 10 |
8| 4 | Managed Kubernetes | 60 |
9| 5 | Load Balancer | 10 |
10+------------+-------------------------+-------+
115 rows in set (0.00 sec)
对于 test_user 的 MySQL 会话结束:
1quit;
一旦设置了test_store
数据库、产品
表和test_user
表,您将编码一个PHP脚本,从MySQL数据库中获取数据并将其缓存到Redis。
步骤 3 — 设计一个 PHP 脚本来检索和缓存 MySQL 数据
在此步骤中,您将创建一个PHP脚本来检索您在上一步创建的样本数据。
当你第一次运行脚本时,它会从MySQL(即从磁盘)读取数据,然后将其缓存到Redis。因此,产品数据的后续读取将来自Redis(即从系统内存)。
<$>[注] **注:**虽然您可能不会得到任何性能提升,因为您只从MySQL数据库中获取几个记录,但几个基准证明从Redis获取缓存数据的速度比从MySQL读取几十万个记录更快。
在您的网站的 root 目录中创建一个 products.php
文件:
1sudo nano /var/www/html/products.php
要开始,请输入以下信息,以连接并创建 Redis 实例,并将其存储为$redis
变量中的对象。
地址 127.0.0.1
连接到 localhost
. 如果您从远程服务器运行 Redis,您可以更改此值. 请记住,在 /etc/redis/redis.conf
配置文件中,用对 Redis 设置的特定密码取代 `REDIS_PASSWORD。
此外,输入相应的端口号码. 默认情况下,Redis 在端口 6379
上运行:
1[label /var/www/html/products.php]
2<?php
3
4$redis = new Redis();
5$redis->connect('127.0.0.1', 6379);
6$redis->auth('REDIS_PASSWORD');
<$>[注]
注: 在本指南中,命令 $redis->auth ('REDIS_PASSWORD')
以简单的文本发送您的密码到 Redis. 在生产环境中,您可能会考虑确保 Redis 与运行 PHP 代码的客户端服务器之间的端到端通信,使用更强大的访问控制层,例如 TLS (Transport Layer Security)。
下一步是初始化您将在 Redis 中使用的 PHP 变量作为密钥。
正如本指南早些时候提到的,Redis 作为一个关键值数据库,因此您必须为您打算存储和从其中获取的数据提供一个独特的密钥。
因此,通过将以下信息添加到 /var/www/html/products.php
文件中来定义一个 PRODUCTS
密钥,您可以自由使用任何名称代替 PRODUCTS
密钥。
您的PHP脚本将使用此密钥将信息缓存到Redis,一旦数据从MySQL数据库中获取:
1[label /var/www/html/products.php]
2...
3$key = 'PRODUCTS';
接下来,包括一个有条件的PHPif...else
声明来检查在Redis中是否存在PRODUCTS
密钥:
1[label /var/www/html/products.php]
2...
3if (!$redis->get($key)) {
4 $source = 'MySQL Server';
5 $database_name = 'test_store';
6 $database_user = 'test_user';
7 $database_password = 'PASSWORD';
8 $mysql_host = 'localhost';
9
10 $pdo = new PDO('mysql:host=' . $mysql_host . '; dbname=' . $database_name, $database_user, $database_password);
11 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
12
13 $sql = "SELECT * FROM products";
14 $stmt = $pdo->prepare($sql);
15 $stmt->execute();
16
17 while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
18 $products[] = $row;
19 }
20
21 $redis->set($key, serialize($products));
22 $redis->expire($key, 10);
23
24} else {
25 $source = 'Redis Server';
26 $products = unserialize($redis->get($key));
27
28}
29
30echo $source . ': <br>';
31print_r($products);
如果 Redis 中没有密钥,则脚本将连接到您之前创建的数据库,查询产品
表,并使用$redis->set($key, serialize($products))
命令将数据存储在 Redis 中。
$redis-> expire($key, 10);
命令将期限设置为10秒
。
$source
变量可帮助您识别数据的来源,一旦使用echo $source
和print_r($products)
命令在脚本末尾以数组响应。
一旦你把一切都放在一起,你的 /var/www/html/products.php
文件将如下:
1[label /var/www/html/products.php]
2<?php
3
4$redis = new Redis();
5$redis->connect('127.0.0.1', 6379);
6$redis->auth('REDIS_PASSWORD');
7
8$key = 'PRODUCTS';
9
10if (!$redis->get($key)) {
11 $source = 'MySQL Server';
12 $database_name = 'test_store';
13 $database_user = 'test_user';
14 $database_password = 'PASSWORD';
15 $mysql_host = 'localhost';
16
17 $pdo = new PDO('mysql:host=' . $mysql_host . '; dbname=' . $database_name, $database_user, $database_password);
18 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
19
20 $sql = "SELECT * FROM products";
21 $stmt = $pdo->prepare($sql);
22 $stmt->execute();
23
24 while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
25 $products[] = $row;
26 }
27
28 $redis->set($key, serialize($products));
29 $redis->expire($key, 10);
30
31} else {
32 $source = 'Redis Server';
33 $products = unserialize($redis->get($key));
34
35}
36
37echo $source . ': <br>';
38print_r($products);
保存并关闭文件。
您现在已经设置了一个PHP脚本,将连接到MySQL并将数据缓存到Redis。
第4步:测试PHP脚本
要测试 Redis 是否正在从 MySQL 数据库中缓存数据,您将在浏览器窗口中输入 PHP 脚本的路径。 请记住用您的服务器的公共 IP 地址取代 your_server_IP
,例如: http://your_server_IP/products.php
。
当您首次运行脚本时,您将收到以下输出,显示来自MySQL数据库的数据,因为此时,PHP脚本尚未在Redis中缓存任何数据:
1MySQL Server
2Array ( [0] => Array ( [product_id] => 1 [product_name] => Virtual Private Servers [price] => 5 ) [1] => Array ( [product_id] => 2 [product_name] => Managed Databases [price] => 15 ) [2] => Array ( [product_id] => 3 [product_name] => Block Storage [price] => 10 ) [3] => Array ( [product_id] => 4 [product_name] => Managed Kubernetes [price] => 60 ) [4] => Array ( [product_id] => 5 [product_name] => Load Balancer [price] => 10 ) )
一旦您重新运行脚本,您将收到一个输出,确认它正在读取来自Redis的数据,该数据作为MySQL的缓存。
1Redis Server
2Array ( [0] => Array ( [product_id] => 1 [product_name] => Virtual Private Servers [price] => 5 ) [1] => Array ( [product_id] => 2 [product_name] => Managed Databases [price] => 15 ) [2] => Array ( [product_id] => 3 [product_name] => Block Storage [price] => 10 ) [3] => Array ( [product_id] => 4 [product_name] => Managed Kubernetes [price] => 60 ) [4] => Array ( [product_id] => 5 [product_name] => Load Balancer [price] => 10 ) )
请记住,密钥将在 10 秒后到期,然后从 MySQL 恢复数据。
结论
在本指南中,您已经使用了 Redis 来缓存 MySQL 数据在 Ubuntu 20.04 上,您可以使用本指南中的编码来为您的 MySQL 数据设置缓存机制,这对于高流量 Web 应用程序尤其有用。
您可以查看我们的 Redis 主题页面以获取更多教育资源,或者,在 PHP 主题页面上了解更多关于 PHP 编码的更多教程和内容。