void Master::MessageReceived(ChannelHandlerContext& ctx, MessageEvent<RedisCommandFrame>& e) { RedisCommandFrame* cmd = e.GetMessage(); DEBUG_LOG("Master recv cmd from slave:%s", cmd->ToString().c_str()); if (!strcasecmp(cmd->GetCommand().c_str(), "replconf")) { if (cmd->GetArguments().size() == 2 && !strcasecmp(cmd->GetArguments()[0].c_str(), "ack")) { int64 offset; if (string_toint64(cmd->GetArguments()[1], offset)) { SlaveConnTable::iterator found = m_slaves.find(ctx.GetChannel()->GetID()); if (found != m_slaves.end()) { SlaveConn* slave = found->second; if (NULL != slave) { slave->acktime = time(NULL); slave->ack_offset = offset; } } } } } }
void Slave::HandleRedisCommand(Channel* ch, RedisCommandFrame& cmd) { int flag = ARDB_PROCESS_REPL_WRITE; if (m_slave_state == SLAVE_STATE_SYNCED || m_slave_state == SLAVE_STATE_LOADING_DUMP_DATA) { flag |= ARDB_PROCESS_FORCE_REPLICATION; } else { flag |= ARDB_PROCESS_WITHOUT_REPLICATION; } DEBUG_LOG("Recv master cmd %s at %lld at flag:%d at state:%d", cmd.ToString().c_str(), m_backlog.GetReplEndOffset(), flag, m_slave_state); if (m_slave_state == SLAVE_STATE_WAITING_PSYNC_REPLY && m_server_type == ARDB_DB_SERVER_TYPE) { if (!strcasecmp(cmd.GetCommand().c_str(), "FULLSYNCED")) { uint64 offset, cksm; string_touint64(cmd.GetArguments()[0], offset); string_touint64(cmd.GetArguments()[1], cksm); m_backlog.SetChecksum(cksm); ASSERT(offset == m_backlog.GetReplEndOffset()); //m_backlog.SetReplOffset(offset); m_slave_state = SLAVE_STATE_SYNCED; //Disconnect all slaves when all data resynced m_serv->m_master_serv.DisconnectAllSlaves(); return; } } if (!strcasecmp(cmd.GetCommand().c_str(), "PING")) { m_ping_recved_time = time(NULL); } else if (!strcasecmp(cmd.GetCommand().c_str(), "SELECT")) { DBID id = 0; string_touint32(cmd.GetArguments()[0], id); m_backlog.SetCurrentDBID(id); } GetArdbConnContext(); m_actx->is_slave_conn = true; m_actx->conn = ch; if (strcasecmp(cmd.GetCommand().c_str(), "SELECT") && strcasecmp(cmd.GetCommand().c_str(), "__SET__") && strcasecmp(cmd.GetCommand().c_str(), "__DEL__")) { if (!m_include_dbs.empty() && m_include_dbs.count(m_actx->currentDB) == 0) { flag |= ARDB_PROCESS_FEED_REPLICATION_ONLY; } if (!m_exclude_dbs.empty() && m_exclude_dbs.count(m_actx->currentDB) > 0) { flag |= ARDB_PROCESS_FEED_REPLICATION_ONLY; } } m_serv->ProcessRedisCommand(*m_actx, cmd, flag); }
void Master::AddSlave(Channel* slave, RedisCommandFrame& cmd) { DEBUG_LOG("Recv sync command:%s", cmd.ToString().c_str()); slave->Flush(); SlaveConnection* conn = NULL; NEW(conn, SlaveConnection); conn->conn = slave; if (!strcasecmp(cmd.GetCommand().c_str(), "sync")) { //Redis 2.6/2.4 send 'sync' conn->isRedisSlave = true; conn->sync_offset = -1; } else { conn->server_key = cmd.GetArguments()[0]; const std::string& offset_str = cmd.GetArguments()[1]; if (!string_toint64(offset_str, conn->sync_offset)) { ERROR_LOG("Invalid offset argument:%s", offset_str.c_str()); slave->Close(); DELETE(conn); return; } //Redis 2.8+ send psync, Ardb send psync2 if (!strcasecmp(cmd.GetCommand().c_str(), "psync")) { conn->isRedisSlave = true; } else { conn->isRedisSlave = false; if (cmd.GetArguments().size() >= 3) { std::vector<std::string> ss = split_string(cmd.GetArguments()[2], "|"); for (uint32 i = 0; i < ss.size(); i++) { DBID id; if (string_touint32(ss[i], id)) { conn->syncdbs.insert(id); } } } } } m_server->m_service->DetachChannel(slave, true); ReplicationInstruction inst(conn, REPL_INSTRUCTION_ADD_SLAVE); OfferReplInstruction(inst); }
void Master::AddSlave(Channel* slave, RedisCommandFrame& cmd) { INFO_LOG("[Master]Recv sync command:%s", cmd.ToString().c_str()); slave->Flush(); SlaveConn& conn = GetSlaveConn(slave); if (!strcasecmp(cmd.GetCommand().c_str(), "sync")) { //Redis 2.6/2.4 send 'sync' conn.isRedisSlave = true; conn.sync_offset = -1; } else { conn.server_key = cmd.GetArguments()[0]; const std::string& offset_str = cmd.GetArguments()[1]; if (!string_toint64(offset_str, conn.sync_offset)) { ERROR_LOG("Invalid offset argument:%s", offset_str.c_str()); slave->Close(); return; } conn.isRedisSlave = true; for (uint32 i = 2; i < cmd.GetArguments().size(); i += 2) { if (cmd.GetArguments()[i] == "cksm") { conn.isRedisSlave = false; if (!string_touint64(cmd.GetArguments()[i + 1], conn.sync_cksm)) { ERROR_LOG("Invalid checksum argument:%s", cmd.GetArguments()[i + 1].c_str()); slave->Close(); return; } } } } slave->GetService().DetachChannel(slave, true); if (g_repl->GetIOServ().IsInLoopThread()) { AddSlave(&conn); } else { g_repl->GetIOServ().AsyncIO(0, OnAddSlave, &conn); } }
/* * GEOADD key MERCATOR|WGS84 x y value [attr_name attr_value ...] */ int ArdbServer::GeoAdd(ArdbConnContext& ctx, RedisCommandFrame& cmd) { GeoAddOptions options; std::string err; if (0 != options.Parse(cmd.GetArguments(), err, 1)) { fill_error_reply(ctx.reply, "%s", err.c_str()); return 0; } int ret = m_db->GeoAdd(ctx.currentDB, cmd.GetArguments()[0], options); CHECK_ARDB_RETURN_VALUE(ctx.reply, ret); if (ret >= 0) { fill_status_reply(ctx.reply, "OK"); } else { fill_error_reply(ctx.reply, "Failed to %s", cmd.ToString().c_str()); } return 0; }