- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试将现有 key 从 Redis 实例 (A) 移动到另一个实例 (B) 而不会丢失 B 的 key 。有什么工具可以使用还是我应该自己写代码?
最佳答案
根据 Redis 官方集群教程:“......然而,目前 redis-trib 无法自动重新平衡集群,检查集群节点间键的分布,并根据需要智能地移动插槽。将添加此功能将来。”
因此您需要自己编写代码将 key 分发给 Redis 实例。如果要将一个或多个键从一个节点迁移到另一个节点,则必须先迁移哈希槽,然后再迁移实际键,否则会发生错误。
通常,您需要一个代码过程来执行这些 Ruby 代码行(redis-trib.rb 中的原型(prototype)):
将槽从源节点迁移到目标节点的代码
target.r.cluster("setslot",slot,"importing",source.info[:name])
source.r.cluster("setslot",slot,"migrating",target.info[:name])
迁移实际 key 的代码
source.r.client.call(["migrate",target.info[:host],target.info[:port],$keys_of_source[i],0,15000]).
您可以使用现有代码从此处进行迁移:https://github.com/projecteru/redis-trib.py
您可以使用这些代码行:
def migrate_slots_stable(src_host, src_port, dst_host, dst_port, slots):
if src_host == dst_host and src_port == dst_port:
raise ValueError('The source and the target node are the same. A good reason is that the key is stored already on target node!')
with Connection( src_host, src_port ) as t:
nodes, myself = _list_masters( t, src_host)
slots = set( slots )
print('\x1b[6;30;42m' + '*****************************************MIGRATION PROCEDURE******************************************' + '\x1b[0m')
print('\x1b[6;30;42m' + '******************************************************************************************************' + '\x1b[0m')
print '* Migrating slots: ', slots , "* \n"
for n in nodes:
if n.host == dst_host and n.port == dst_port:
return _migr_slots_stable( myself, n, slots, nodes )
#raise ValueError( 'Two nodes are not in the same cluster' )
def _migr_slots_stable(source_node, target_node, slots, nodes):
key_count = 0
for slot in slots:
key_count += _migr_one_slot_stable(source_node, target_node, slot, nodes)
_migr_one_slot_stable( source_node, target_node, slot, nodes )
#print "* keys_count that exists in these slot(s): ", key_count,' *'
#print "\n"
#print '* Migrated succesfully:',len(slots),'slot(s) and ',key_count,'key(s) from SOURCE NODE --> node_id:',source_node.node_id,'host:',source_node.host,'port:',source_node.port,'to TARGET NODE --> node_id:', target_node.node_id,'host:',target_node.host,'port:',target_node.port,' *'
#print('\x1b[6;30;42m' + '******************************************************************************************************' + '\x1b[0m')
print "\n"
def _migr_one_slot_stable(source_node, target_node, slot, nodes):
def expect_exec_ok(m, conn, slot):
if m.lower() != 'ok':
conn.raise_('\n'.join([
'Error while moving slot [ %d ] between' % slot,
'Source node - %s:%d' % (source_node.host, source_node.port),
'Target node - %s:%d' % (target_node.host, target_node.port),
'Got %s' % m]))
# Set the new node as the owner of the slot in all the known nodes
# Bind the hash slot to a different node
@retry(stop_max_attempt_number=16, wait_fixed=100)
def setslot_stable(conn, slot, node_id):
m = conn.execute('cluster', 'setslot', slot, 'node', node_id)
expect_exec_ok(m, conn, slot)
source_conn = source_node.get_conn()
target_conn = target_node.get_conn()
# Same in Ruby with these lines of code
# the target node importing the slot and the source node migrating it
try:
expect_exec_ok(
target_conn.execute('cluster', 'setslot', slot, 'importing',
source_node.node_id),
target_conn, slot)
except hiredis.ReplyError, e:
if 'already the owner of' not in e.message:
target_conn.raise_(e.message)
try:
expect_exec_ok(
source_conn.execute('cluster', 'setslot', slot, 'migrating',
target_node.node_id),
source_conn, slot)
except hiredis.ReplyError, e:
if 'not the owner of' not in e.message:
source_conn.raise_(e.message)
keys = _migr_keys_stable(source_conn, target_node.host, target_node.port, slot)
setslot_stable(source_conn, slot, target_node.node_id)
for node in nodes:
setslot_stable(node.get_conn(), slot, target_node.node_id)
return keys
def _migr_keys_stable(src_conn, target_host, target_port, slot):
key_count = 0
while True:
keys = src_conn.execute('cluster', 'getkeysinslot', slot, 10)
if len(keys) == 0:
return key_count
key_count += len(keys)
src_conn.execute_bulk(
# Same in Ruby with this line of code: source.r.client.call(["migrate",target.info[:host],target.info[:port],$keys_of_source[i],0,15000])
[['migrate', target_host, target_port, k, 0, 30000] for k in keys])
触发的第一个函数是def migrate_slots_stable
,参数包括源主机、源端口、目标主机、目标端口和一组要传输的哈希槽。
关于python - 如何将redis键添加到另一个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45262691/
我有一个关于 Redis Pubsub 的练习,如下所示: 如果发布者发布消息但订阅者没有收到服务器崩溃。订阅者如何在重启服务器时收到该消息? 请帮帮我,谢谢! 最佳答案 在这种情况下,消息将永远消失
我们正在使用 Service Stack 的 RedisClient 的 BlockingDequeue 来保存一些数据,直到它可以被处理。调用代码看起来像 using (var client =
我有一个 Redis 服务器和多个 Redis 客户端。每个 Redis 客户端都是一个 WebSocket+HTTP 服务器,其中包括管理 WebSocket 连接。这些 WebSocket+HTT
我有多个 Redis 实例。我使用不同的端口创建了一个集群。现在我想将数据从预先存在的 redis 实例传输到集群。我知道如何将数据从一个实例传输到集群,但是当实例多于一个时,我无法做到这一点。 最佳
配置:三个redis集群分区,跨三组一主一从。当 Master 宕机时,Lettuce 会立即检测到中断并开始重试。但是,Lettuce 没有检测到关联的 slave 已经将自己提升为 master
我想根据从指定集合中检索这些键来删除 Redis 键(及其数据集),例如: HMSET id:1 password 123 category milk HMSET id:2 password 456
我正在编写一个机器人(其中包含要禁用的命令列表),用于监视 Redis。它通过执行禁用命令,例如 (rename-command ZADD "")当我重新启动我的机器人时,如果要禁用的命令列表发生变化
我的任务是为大量听众使用发布/订阅。这是来自 docs 的订阅的简化示例: r = redis.StrictRedis(...) p = r.pubsub() p.subscribe('my-firs
我一直在阅读有关使用 Redis 哨兵进行故障转移的内容。我打算有1个master+1个slave,如果master宕机超过1分钟,就把slave变成master。我知道这在 Sentinel 中是
与仅使用常规 Redis 和创建分片相比,使用 Redis 集群有哪些优势? 在我看来,Redis Cluster 更注重数据安全(让主从架构解决故障)。 最佳答案 我认为当您需要在不丢失任何数据的情
由于 Redis 以被动和主动方式使 key 过期, 有没有办法得到一个 key ,即使它的过期时间已过 (但 在 Redis 中仍然存在 )? 最佳答案 DEBUG OBJECT myKey 将返回
我想用redis lua来实现monitor命令,而不是redis-cli monitor。但我不知道怎么办。 redis.call('monitor') 不起作用。 最佳答案 您不能从 Redis
我读过 https://github.com/redisson/redisson 我发现有几个 Redis 复制设置(包括对 AWS ElastiCache 和 Azure Redis 缓存的支持)
Microsoft.AspNet.SignalR.Redis 和 StackExchange.Redis.Extensions.Core 在同一个项目中使用。前者需要StackExchange.Red
1. 认识 Redis Redis(Remote Dictionary Server)远程词典服务器,是一个基于内存的键值对型 NoSQL 数据库。 特征: 键值(key-value)型,value
1. Redis 数据结构介绍 Redis 是一个 key-value 的数据库,key 一般是 String 类型,但 value 类型多种多样,下面就举了几个例子: value 类型 示例 Str
1. 什么是缓存 缓存(Cache) 就是数据交换的缓冲区,是存贮数据的临时地方,一般读写性能较高。 缓存的作用: 降低后端负载 提高读写效率,降低响应时间 缓存的成本: 数据一致性成本 代码维护成本
我有一份记录 list 。对于我的每条记录,我都需要进行一些繁重的计算,因为我要在Redis中创建反向索引。为了达到到达记录,需要在管道中执行多个redis命令(sadd为100 s + set为1
我有一个三节点Redis和3节点哨兵,一切正常,所有主服务器和从属服务器都经过验证,并且哨兵配置文件已与所有Redis和哨兵节点一起更新,但是问题是当Redis主服务器关闭并且哨兵希望选举失败者时再次
我正在尝试计算Redis中存储的消息之间的响应时间。但是我不知道该怎么做。 首先,我必须像这样存储chat_messages的时间流 ZADD conversation:CONVERSATION_ID
我是一名优秀的程序员,十分优秀!