Example #1
0
//===================================encoder==============================
bool RedisCommandEncoder::Encode(Buffer& buf, const RedisCommandFrame& cmd)
{
    buf.Printf("*%d\r\n", cmd.GetArguments().size() + 1);
    buf.Printf("$%d\r\n", cmd.GetCommand().size());
    buf.Write(cmd.GetCommand().data(), cmd.GetCommand().size());
    buf.Write("\r\n", 2);
    for (uint32 i = 0; i < cmd.GetArguments().size(); i++)
    {
        const std::string* arg = cmd.GetArgument(i);
        buf.Printf("$%d\r\n", arg->size());
        buf.Write(arg->data(), arg->size());
        buf.Write("\r\n", 2);
    }
    return true;
}
Example #2
0
	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);
	}
Example #3
0
 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;
                     }
                 }
             }
         }
     }
 }
Example #4
0
	int ArdbServer::Exec(ArdbConnContext& ctx, RedisCommandFrame& cmd)
	{
		if (ctx.fail_transc || !ctx.in_transaction)
		{
			ctx.reply.type = REDIS_REPLY_NIL;
		}
		else
		{
			RedisReply r;
			r.type = REDIS_REPLY_ARRAY;
			if (NULL != ctx.transaction_cmds)
			{
				for (uint32 i = 0; i < ctx.transaction_cmds->size(); i++)
				{
					RedisCommandFrame& cmd = ctx.transaction_cmds->at(i);
					DoRedisCommand(ctx,
					        FindRedisCommandHandlerSetting(cmd.GetCommand()),
					        cmd);
					r.elements.push_back(ctx.reply);
				}
			}
			ctx.reply = r;
		}
		ctx.in_transaction = false;
		DELETE(ctx.transaction_cmds);
		ClearWatchKeys(ctx);
		return 0;
	}
Example #5
0
    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);
    }
Example #6
0
 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);
     }
 }