Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Caching Redis管道,处理缓存未命中_Caching_Redis_Pipelining - Fatal编程技术网

Caching Redis管道,处理缓存未命中

Caching Redis管道,处理缓存未命中,caching,redis,pipelining,Caching,Redis,Pipelining,我正试图找出实现Redis管道的最佳方法。我们使用redis作为MySQL之上的缓存来存储用户数据、产品列表等。 我以此为出发点: 我的问题是,假设您有一个正确排序的ID数组。您可以像这样在redis管道中循环: $redis = new Redis(); // Opens up the pipeline $pipe = $redis->multi(Redis::PIPELINE); // Loops through the data and performs actions fore

我正试图找出实现Redis管道的最佳方法。我们使用redis作为MySQL之上的缓存来存储用户数据、产品列表等。 我以此为出发点:

我的问题是,假设您有一个正确排序的ID数组。您可以像这样在redis管道中循环:

$redis = new Redis();

// Opens up the pipeline
$pipe = $redis->multi(Redis::PIPELINE);

// Loops through the data and performs actions
foreach ($users as $user_id => $username)
{
    // Increment the number of times the user record has been accessed
    $pipe->incr('accessed:' . $user_id);

    // Pulls the user record
    $pipe->get('user:' . $user_id);
}

// Executes all of the commands in one shot
$users = $pipe->exec();
$pipe->get('user:'。$user\u id)时会发生什么情况
不可用,因为它以前没有被请求过,或者已经被Redis逐出,等等?假设它是50的结果#13,我们如何a)发现我们无法检索该对象,b)保持用户数组正确排序


谢谢

我将回答有关Redis协议的问题。在这种情况下,它在特定语言中的工作原理大致相同

首先,让我们看看Redis管道是如何工作的: 这只是一种向服务器发送多个命令、执行它们并获得多个回复的方法。没有什么特别的,您只是得到一个数组,其中包含管道中每个命令的回复

管道之所以快得多,是因为每个命令都节省了往返时间,即对于100个命令,只有一个往返时间,而不是100个。此外,Redis同步执行每个命令。执行100条命令可能需要100次战斗,对于Redis来说,要拾取单个命令,管道被视为一条长命令,因此只需要一次等待同步拾取

您可以在此处阅读有关管道的更多信息:。还有一点需要注意,因为每个流水线批处理都不间断地运行(就Redis而言),所以有必要将这些命令分为可查看的块发送,即不要在单个管道中发送100k命令,这可能会长时间阻止Redis,将它们分为1k或10k个命令块

在本例中,您在循环中运行以下片段:

// Increment the number of times the user record has been accessed
$pipe->incr('accessed:' . $user_id);

// Pulls the user record
$pipe->get('user:' . $user_id);
问题是什么被投入管道?假设您要将
u1
u2
u3
u4
的数据更新为用户ID。因此,带有Redis命令的管道将如下所示:

INCR accessed:u1
GET user:u1
INCR accessed:u2
GET user:u2
INCR accessed:u3
GET user:u3
INCR accessed:u4
GET user:u4
比如说:

  • u1以前被访问过100次
  • u2之前被访问过5次
  • 之前和之后未访问u3
  • u4和相关数据不存在
在这种情况下,结果将是一个Redis回复数组,具有:

101
u1 string data stored at user:u1
6
u2 string data stored at user:u2
1
u3 string data stored at user:u3
1
NIL
如您所见,Redis将把缺少的增量值视为
0
,并执行
INCR(0)
。最后,Redis没有对任何内容进行排序,结果将根据请求进入排序器


语言绑定(例如Redis驱动程序)将为您解析该协议,并提供解析数据的视图。如果不保持命令的顺序,Redis驱动程序就不可能正常工作,程序员也不可能推断smth。请记住,该请求不会在回复中重复,即在执行
GET
时,您不会收到
u1
u2
的密钥,而只会收到该密钥的数据。因此,您的实现必须记住,在位置
1
(零基索引)上,对于
u1
GET
,我将回答有关Redis协议的问题。在这种情况下,它在特定语言中的工作原理大致相同

首先,让我们看看Redis管道是如何工作的: 这只是一种向服务器发送多个命令、执行它们并获得多个回复的方法。没有什么特别的,您只是得到一个数组,其中包含管道中每个命令的回复

管道之所以快得多,是因为每个命令都节省了往返时间,即对于100个命令,只有一个往返时间,而不是100个。此外,Redis同步执行每个命令。执行100条命令可能需要100次战斗,对于Redis来说,要拾取单个命令,管道被视为一条长命令,因此只需要一次等待同步拾取

您可以在此处阅读有关管道的更多信息:。还有一点需要注意,因为每个流水线批处理都不间断地运行(就Redis而言),所以有必要将这些命令分为可查看的块发送,即不要在单个管道中发送100k命令,这可能会长时间阻止Redis,将它们分为1k或10k个命令块

在本例中,您在循环中运行以下片段:

// Increment the number of times the user record has been accessed
$pipe->incr('accessed:' . $user_id);

// Pulls the user record
$pipe->get('user:' . $user_id);
问题是什么被投入管道?假设您要将
u1
u2
u3
u4
的数据更新为用户ID。因此,带有Redis命令的管道将如下所示:

INCR accessed:u1
GET user:u1
INCR accessed:u2
GET user:u2
INCR accessed:u3
GET user:u3
INCR accessed:u4
GET user:u4
比如说:

  • u1以前被访问过100次
  • u2之前被访问过5次
  • 之前和之后未访问u3
  • u4和相关数据不存在
在这种情况下,结果将是一个Redis回复数组,具有:

101
u1 string data stored at user:u1
6
u2 string data stored at user:u2
1
u3 string data stored at user:u3
1
NIL
如您所见,Redis将把缺少的增量值视为
0
,并执行
INCR(0)
。最后,Redis没有对任何内容进行排序,结果将根据请求进入排序器

语言绑定(例如Redis驱动程序)将为您解析该协议,并提供解析数据的视图。如果不保持命令的顺序,Redis驱动程序就不可能正常工作,程序员也不可能推断smth。请记住,该请求不会在回复中重复,即在执行
GET
时,您不会收到
u1
u2
的密钥,而只会收到该密钥的数据。因此,您的实现必须记住,在位置
1
(基于零的索引)上,对于
u1
,会产生
GET