为什么我们要使用Redis,在PHP中正确实现Redis和MySql的方式是什么?

20

我在数据库中有大量数据,有时当结果的执行时间超过服务器响应时间时,服务器会停止响应。那么,有没有办法通过Redis来减轻Mysql服务器的负载,并且该如何正确实现呢?

2个回答

24

Redis支持多种数据类型,你可能会想一个NOSQL键值存储与数据类型有什么关系?这些数据类型帮助开发人员以有意义的方式存储数据,并可以使数据检索更快。

在PHP中连接Redis

1)从GitHub下载或克隆predis库。

2)我们将需要Redis自动加载程序并进行注册。然后,我们将在try catch块中包装客户端。连接到本地服务器上的Redis的连接设置与连接到远程服务器不同。

require "predis/autoload.php";
PredisAutoloader::register();

try {
    $redis = new PredisClient();

    // This connection is for a remote server
    /*
        $redis = new PredisClient(array(
            "scheme" => "tcp",
            "host" => "153.202.124.2",
            "port" => 6379
        ));
    */
}
catch (Exception $e) {
    die($e->getMessage());
}

现在我们已经成功连接到Redis服务器,让我们开始使用Redis。

Redis的数据类型

以下是Redis支持的一些数据类型:

  • 字符串(String):与PHP中的字符串类似。
  • 列表(List):类似于PHP中的单维数组。您可以推入(push)、弹出(pop)、左侧推出(shift)和左侧插入(unshift)按顺序或插入FIFO(先进先出)放置的元素。
  • 哈希(Hash):在字符串字段和字符串值之间进行映射。它们是表示对象的完美数据类型(例如:具有名称、姓氏等多个字段的用户)。
  • 集合(Set):类似于列表,但它没有顺序,并且每个元素只能出现一次。
  • 有序集合(Sorted Set):类似于Redis集合,具有将值存储在集合中的独特功能。不同之处在于,有序集合的每个成员都与分数相关联,用于将集合从最小分数到最大分数排序。 其他的比特图和HyperLogLogs本文不会讨论,因为它们比较复杂。

PHP Redis(Predis)中的Getter和Setter

在Redis中,最重要的命令是SET、GET和EXISTS。这些命令用于将数据存储、检查和检索从Redis服务器中。就像命令一样,Predis类可以通过与命令名称相同的方法执行Redis操作。例如:

// sets message to contian "Hello world"
$redis->set('message', 'Hello world');
// gets the value of message
$value = $redis->get('message');
// Hello world
print($value); 
echo ($redis->exists('message')) ? "Oui" : "please populate the message key";

INCR 和 DECR 是用于增加或减少一个值的命令。

$redis->set("counter", 0);
$redis->incr("counter"); // 1
$redis->incr("counter"); // 2
$redis->decr("counter"); // 1


$redis->set("counter", 0);
$redis->incrby("counter", 15); // 15
$redis->incrby("counter", 5);  // 20
$redis->decrby("counter", 10); // 10

使用列表

Redis中处理列表的基本命令如下:

  • LPUSH:将元素添加到列表的开头
  • RPUSH:将元素添加到列表的末尾
  • LPOP:移除并返回列表的第一个元素
  • RPOP:移除并返回列表的最后一个元素
  • LLEN:获取列表的长度
  • LRANGE:获取列表中指定范围内的元素

如下所示的示例:

$redis->rpush("languages", "french"); // [french]
$redis->rpush("languages", "arabic"); // [french, arabic]
$redis->lpush("languages", "english"); // [english, french, arabic]
$redis->lpush("languages", "swedish"); // [swedish, english, french, arabic]
$redis->lpop("languages"); // [english, french, arabic]
$redis->rpop("languages"); // [english, french]
$redis->llen("languages"); // 2
$redis->lrange("languages", 0, -1); // returns all elements
$redis->lrange("languages", 0, 1); // [english, french]

如何将Redis中的数据检索到MySQL

你需要将Redis数据库设为主数据库,将Mysql数据库设为从数据库。这意味着你需要首先从Redis中获取数据,如果没有找到/检索到数据,那么再从MySQL中获取数据。如果找到数据,则更新Redis数据,这样下一次就可以从Redis中检索数据。基本快照如下所示。

//Connect with Redis database
$data=get_data_redis($query_param);
if(empty($data))
{
  //connect with mysql
  $data=get_data_mysql($query_param);
  if(!empty($data))
  {
     // update data into redis for that data
    update_data_redis($data,$query_param);
  }
}

如何在MySQL和Redis中管理数据

如果需要将数据存储到数据库中,您需要先将数据更新到MySQL数据库,然后再更新到Redis数据库。

//insert data in mysql
$inserted= insert_data_mysql($data);
if($inserted)
{
    insert_data_redis($data);
}

//update data in mysql
$updated= update_data_mysql($data,$query);
if($updated)
{
    insert_data_redis($data,$query);
}

//delete data in mysql
$deleted= delete_data_mysql($query);
if($deleted)
{
    delete_data_redis($query);
}

添加了Snapecode以处理MySQL和Redis数据库,用于管理数据和检索数据。 - Haresh Vidja

18

Redis可以作为MYSQL查询的缓存层。Redis是内存数据库,这意味着它将保留数据在内存中,并且与从MYSQL查询数据相比,可以更快地访问数据。

一个示例用例:

假设您正在创建一个游戏列表网站,您有多个游戏类别,例如汽车游戏,自行车游戏,儿童游戏等,为了在游戏列表页面中查找每个类别的游戏映射,您必须查询SQL数据库以获取游戏列表。这是一种可以使用Redis作为缓存层的场景,并在memcahce / Radis中缓存SQL响应X小时。

确切步骤:

  1. 首先从Redis获取
  2. 如果在redis中找到,则返回。 如果未在redis中找到,则执行MYSQL查询,并在返回之前将响应保存在redis缓存中,以备下次使用。

这将从MYSQL中卸载大量查询到内存中的redis数据库。

if(data in redis){
    step 1: return data;
}else{
    step 1: query MYSQL
    step 2: Save in redis
    step 3: return data
}

在选择要保存在Redis中的查询之前,请考虑以下几点:

  1. 只选择静态查询,即数据不是特定于用户的查询。
  2. 选择慢的静态查询以进一步提高MYSQL性能。

希望这能有所帮助。


1
数据库(在这种情况下是mysql)可以调整以缓存查询。它也运行得相当不错。 - Sergio Tulentsev
嗨Sergio,就我个人而言,我从未在MySQL中使用过查询缓存,但是我阅读了下面的文章http://dev.mysql.com/doc/refman/5.7/en/query-cache.html,它似乎非常有用,我会在下一个项目中使用它。谢谢。 - Nishant
嗨Sergio,我们可以将缓存查询用于特定用户查询或动态查询结果吗? - astha
@astha:- MySQL和Redis缓存都可以用于动态查询,MySQL缓存会自动处理,而对于Redis缓存,我们需要使用userId创建键。 - Nishant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接