1

问题Redis的主从复制 - 对从

我有一个情况似乎在那里,我在主创建的数据并没有被正确地复制到我的奴隶丢失的数据。

主Redis的DB设置信息

我有10.1.1.1运行的主。配置设置为“保存”到磁盘。下面是从配置文件中的一个片段:

save 900 1 
save 300 10 
save 60 10000 

当我运行针对有问题的散列扫描命令,这里的结果(这是正确的):

127.0.0.1:6379> scan 0 match dep:* 
1) "13" 
2) 1) "dep:+19999999999_00:00_00:00" 
    2) "dep:+19999999999_19:00_25:00" 
    3) "dep:+19999999999_08:00_12:00" 
127.0.0.1:6379> 

从1设置

从机1已设置为仅在内存中运行。所以在配置文件中,所有的“保存”选项都被注释掉了。

下面是我在从1中的数据:(缺少记录)

127.0.0.1:6379> scan 0 match dep:* 
1) "15" 
2) 1) "dep:+19999999999_00:00_00:00" 
    2) "dep:+19999999999_19:00_25:00" 
127.0.0.1:6379> 

当我运行这个从“信息”命令,这是我得到的结果:(只挑选特定的项目,我认为可能涉及到这个问题)

# Replication 
role:slave 
master_host:10.1.1.1 
master_port:6379 
master_link_status:up 
master_last_io_seconds_ago:5 
master_sync_in_progress:0 
slave_repl_offset:346292 
slave_priority:100 
slave_read_only:1 
connected_slaves:0 
master_repl_offset:0 
repl_backlog_active:0 
repl_backlog_size:1048576 
repl_backlog_first_byte_offset:0 
repl_backlog_histlen:0 

#Stats 
expired_keys:0 

#Persistence 
aof_enabled:0 

从2安装

从2也应该是一个只在内存中的数据存储。因此,所有的配置文件中保存的选项也被注释掉,象这样:

#save 900 1 
#save 300 10 
#save 60 10000 

这是我对奴隶2中的数据(请注意,它缺少数据,而是从从1不同的记录)

127.0.0.1:6379> scan 0 match dep:* 
1) "3" 
2) 1) "dep:+19999999999_00:00_00:00" 
    2) "dep:+19999999999_08:00_12:00" 
127.0.0.1:6379> 

一些来自info命令的结果:

# Replication 
role:slave 
master_host:10.1.1.1 
master_port:6379 
master_link_status:up 
master_last_io_seconds_ago:3 
master_sync_in_progress:0 
slave_repl_offset:346754 
slave_priority:100 
slave_read_only:1 
connected_slaves:0 
master_repl_offset:0 
repl_backlog_active:0 
repl_backlog_size:1048576 
repl_backlog_first_byte_offset:0 
repl_backlog_histlen:0 

#Stats 
expired_keys:0 

#Persistence 
aof_enabled:0 

这是我在使用Redis的第一条裂缝,所以我敢肯定这件事情简单,我已经错过了。 我还没有尝试在从属设备上重新启动REDIS,因为我不想失去任何可能帮助我排除故障/理解我在这里首先获得的东西的工件。

任何建议,将不胜感激。

编辑1

在检查上从2日志,这是我发现:

4651:S 27 Sep 18:39:27.197 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. 
4651:S 27 Sep 18:39:27.197 # Server started, Redis version 3.0.5 
4651:S 27 Sep 18:39:27.197 * The server is now ready to accept connections on port 6379 
4651:S 27 Sep 18:39:27.198 * Connecting to MASTER 10.1.1.1:6379 
4651:S 27 Sep 18:39:27.198 * MASTER <-> SLAVE sync started 
4651:S 27 Sep 18:40:28.284 # Timeout connecting to the MASTER... 
4651:S 27 Sep 18:40:28.284 * Connecting to MASTER 10.1.1.1:6379 
4651:S 27 Sep 18:40:28.284 * MASTER <-> SLAVE sync started 
4651:S 27 Sep 18:41:29.369 # Timeout connecting to the MASTER... 
4651:S 27 Sep 18:41:29.369 * Connecting to MASTER 10.1.1.1:6379 
4651:S 27 Sep 18:41:29.369 * MASTER <-> SLAVE sync started 
4651:S 27 Sep 18:42:00.452 * Non blocking connect for SYNC fired the event. 
4651:S 27 Sep 18:42:00.453 * Master replied to PING, replication can continue... 
4651:S 27 Sep 18:42:00.453 * Partial resynchronization not possible (no cached master) 
4651:S 27 Sep 18:42:00.463 * Full resync from master: b46c3622e4ef4c5586ebd2ec23eabcb04c3fcf32:1 
4651:S 27 Sep 18:42:00.592 * MASTER <-> SLAVE sync: receiving 173 bytes from master 
4651:S 27 Sep 18:42:00.592 * MASTER <-> SLAVE sync: Flushing old data 
4651:S 27 Sep 18:42:00.592 * MASTER <-> SLAVE sync: Loading DB in memory 
4651:S 27 Sep 18:42:00.592 * MASTER <-> SLAVE sync: Finished with success 

怎么办时,有一个超时连接到主redis的奴隶恢复?我也想知道这个错误是什么意思“部分重新同步不可能(没有缓存大师)”。

目前Google搜寻...但是,如果您有任何意见,请随时

EDIT 2

这里还有一个非常有趣的发现(至少对我来说)。 我只是增加了一个新的项目的主人,就像这样:

127.0.0.1:6379> HMSET dep:+19999999999_15:00_18:45:00 ext 2222 dd me.net days "fri" 
OK 
127.0.0.1:6379> scan 0 match dep:* 
1) "13" 
2) 1) "dep:+19999999999_00:00_00:00" 
    2) "dep:+19999999999_19:00_25:00" 
    3) "dep:+19999999999_15:00_18:45:00" 
    4) "dep:+19999999999_08:00_12:00" 
127.0.0.1:6379> 

而现在,当我再次检查奴隶之一,它仍然只拥有2条记录,但其下降曾经是有一个纪录,并取代它与新的我只是说:

127.0.0.1:6379> scan 0 match dep:* 
1) "7" 
2) 1) "dep:+19999999999_00:00_00:00" 
    2) "dep:+19999999999_15:00_18:45:00" 
127.0.0.1:6379> 

编辑3

从下面的答案,它看起来像由扫描命令返回的第一个数字是光标的位置......而在阅读文档我可以指定一个计数,指出要返回的记录数。 但这仍然给我提出了一些问题。例如,在下面的答案线,我试图在从以下扫描命令:

127.0.0.1:6379> scan 0 match dep:* 
1) "7" 
2) 1) "dep:+19999999999_00:00_00:00" 
    2) "dep:+19999999999_15:00_18:45:00" 
127.0.0.1:6379> scan 7 match dep:* 
1) "0" 
2) 1) "dep:+19999999999_19:00_25:00" 
    2) "dep:+19999999999_08:00_12:00" 
127.0.0.1:6379> 

这是有道理的,我...这似乎在同一时间将返回2条记录(仍需图我怎样才能改变这个默认值)

根据这篇文章 - Redis scan count: How to force SCAN to return all keys matching a pattern? - ,我可以使用“count”关键字来表示有多少记录要返回。

但为了获得所有4条记录,我必须在游标值回到零之前运行几个查询......我不知道为什么。例如:

127.0.0.1:6379> scan 0 match dep:* count 3 
1) "10" 
2) 1) "dep:+19999999999_00:00_00:00" 
127.0.0.1:6379> scan 10 match dep:* count 3 
1) "3" 
2) (empty list or set) 
127.0.0.1:6379> scan 3 match dep:* count 3 
1) "7" 
2) 1) "dep:+19999999999_15:00_18:45:00" 
127.0.0.1:6379> scan 7 match dep:* count 3 
1) "0" 
2) 1) "dep:+19999999999_19:00_25:00" 
    2) "dep:+19999999999_08:00_12:00" 
127.0.0.1:6379> 

为什么第一个请求没有返回3条记录?在我看来,最多我不得不运行这个扫描命令2次。 你能解释一下这里发生了什么?

另外,也许我不应该在我的节点js REST API中使用scan命令?想象一下,一个用户会提出一个小部件信息的请求...我需要查询这个哈希来找到这个密钥。它感觉像这种类型的迭代将是非常低效的。 KEYS命令也可以工作,但根据文档,我不应该在生产中使用它,因为它会影响性能。 任何意见/见解将不胜感激。

回答

1

您还没有迭代Redis实例中的所有密钥。

为了做一个完整的迭代,你应该继续发送SCAN命令到Redis并返回光标,直到返回的光标是0

在您的最后一个例子:

127.0.0.1:6379> scan 0 match dep:* 
1) "7" <---- returned cursor 
2) 1) "dep:+19999999999_00:00_00:00" 
    2) "dep:+19999999999_15:00_18:45:00" 
127.0.0.1:6379> 
// here, you need continue sending scan command with the returned cursor, i.e. 7 
127.0.0.1:6379> scan 7 match dep:* 
// then you can get more results from Redis 
// If the full iteration is finished, it should return something like this: 
1) "0" <----- this means the full iteration is finished 
2) 1) "dep:more result" 
    2) "dep:last result" 

编辑

count numberSCAN命令是只是一个提示。无法保证Redis应该完全返回count number结果(有关更多详细信息,请参阅the doc)。

为了一次性获得所有密钥,您可以使用KEYS命令。然而,正如你所提到的那样,这不是一个好主意(它可能会阻塞Redis很长一段时间),这就是为什么Redis使用SCAN命令来获取所有密钥的迭代。

SCANKEYS这两个命令都遍历整个密钥空间以查找匹配项。因此,如果数据集非常大,则需要很长时间来获取/迭代所有密钥。

从您的问题描述,我觉得你应该存储在Redis的HASH结构中的数据,并使用HKEYSHGETALLHSCAN获取数据:

hset dep:+19999999999 00:00_00:00:00 value 
hset dep:+19999999999 15:00_18:45:00 value 
hkeys dep:+19999999999 <----- get all fields in this hash 
hgetall dep:+19999999999 <----- get all fields and values in this hash 
hscan dep:+19999999999 0 <----- scan the hash to key fields 

这应该是比遍历更有效整个关键空间。尤其是,如果散列中没有太多字段,则HKEYSHGETALL可以一次获得所有密钥/数据,并且速度非常快。但是,如果散列中的字段太多,则仍然需要使用HSCAN来进行迭代。

+0

哇。谢谢!我没有意识到这一点。那么没有办法让所有东西都在一起?或者控制每次迭代中返回的记录数量? – Happydevdays

+0

http://stackoverflow.com/questions/33166812/redis-scan-count-how-to-force-scan-to-return-all-keys-matching-a-pattern – Happydevdays

+0

请参阅编辑3 – Happydevdays