Example #1
0
RedisServantGroup *RedisProxy::group(const char *name) const
{
    for (int i = 0; i < groupCount(); ++i) {
        RedisServantGroup* p = group(i);
        if (strcmp(name, p->groupName()) == 0) {
            return p;
        }
    }
    return NULL;
}
bool CRedisProxyCfg::saveProxyLastState(RedisProxy* proxy) {
    TiXmlElement* pRootNode = (TiXmlElement*)m_operateXmlPointer->get_rootElement();
    string nodeHash = "hash_mapping";
    TiXmlElement* pOldHashMap;
    if (GetNodePointerByName(pRootNode, nodeHash, pOldHashMap)) {
        pRootNode->RemoveChild(pOldHashMap);
    }
    TiXmlElement hashMappingNode("hash_mapping");
    for (int i = 0; i < proxy->slotCount(); ++i) {
        TiXmlElement hashNode("hash");
        hashNode.SetAttribute("value", i);
        hashNode.SetAttribute("group_name", proxy->groupBySlot(i)->groupName());
        hashMappingNode.InsertEndChild(hashNode);
    }
    pRootNode->InsertEndChild(hashMappingNode);

    // key mapping
    string nodeKey = "key_mapping";
    TiXmlElement* pKey;
    if (GetNodePointerByName(pRootNode, nodeKey, pKey)) {
        pRootNode->RemoveChild(pKey);
    }
    TiXmlElement keyMappingNode("key_mapping");

    StringMap<RedisServantGroup*>& keyMapping = proxy->keyMapping();
    StringMap<RedisServantGroup*>::iterator it = keyMapping.begin();
    for (; it != keyMapping.end(); ++it) {
        String key = it->first;
        TiXmlElement keyNode("key");
        keyNode.SetAttribute("key_name", key.data());
        RedisServantGroup* group = it->second;
        if (group != NULL) {
            keyNode.SetAttribute("group_name", group->groupName());
        }
        keyMappingNode.InsertEndChild(keyNode);
    }
    pRootNode->InsertEndChild(keyMappingNode);

    // add time
    time_t now = time(NULL);
    char fileName[512];
    struct tm* current_time = localtime(&now);
    sprintf(fileName,"onecache%d%02d%02d%02d.xml",
        current_time->tm_year + 1900,
        current_time->tm_mon + 1,
        current_time->tm_mday,
        current_time->tm_hour);

    bool ok = m_operateXmlPointer->m_docPointer->SaveFile(fileName);
    return ok;
}
Example #3
0
void RedisProxy::handleClientPacket(const char *key, int len, ClientPacket *packet)
{
    RedisServantGroup* group = mapToGroup(key, len);
    if (!group) {
        packet->setFinishedState(ClientPacket::RequestError);
        return;
    }
    RedisServant* servant = group->findUsableServant(packet);
    if (servant) {
        servant->handle(packet);
    } else {
        if (m_autoEjectGroup) {
            m_groupMutex.lock();
            m_proxyManager.setGroupTTL(group, m_groupRetryTime, m_ejectAfterRestoreEnabled);
            m_groupMutex.unlock();
        }
        packet->setFinishedState(ClientPacket::RequestError);
    }
}
Example #4
0
void startOneCache(void)
{
    CRedisProxyCfg* cfg = CRedisProxyCfg::instance();
    setupSignal();

    EventLoop listenerLoop;
    bool twemproxyMode = cfg->isTwemproxyMode();
    const int points_per_server = 160;
    const int pointer_per_hash = 4;
    int slot_index = 0;

    RedisProxy proxy;
    proxy.setEventLoop(&listenerLoop);
    loop = &listenerLoop;
    CProxyMonitor monitor;
    proxy.setMonitor(&monitor);

    const int defaultPort = 8221;
    int port = cfg->port();
    if (port <= 0) {
        LOG(Logger::Debug, "Port %d invalid, use default port %d", defaultPort);
        port = defaultPort;
    }

    if (!proxy.run(HostAddress(port))) {
        exit(APP_EXIT_KEY);
    }

    proxy.setTwemproxyModeEnabled(twemproxyMode);

    EventLoopThreadPool pool;
    pool.start(cfg->threadNum());
    proxy.setEventLoopThreadPool(&pool);

    const SVipInfo* vipInfo = cfg->vipInfo();
    proxy.setVipName(vipInfo->if_alias_name);
    proxy.setVipAddress(vipInfo->vip_address);
    proxy.setVipEnabled(vipInfo->enable);

    const SHashInfo* sHashInfo = cfg->hashInfo();

    if (!twemproxyMode) {
        proxy.setSlotCount(sHashInfo->hash_value_max);
    } else {
        proxy.setSlotCount(cfg->groupCnt() * points_per_server);
    }

    const GroupOption* groupOption = cfg->groupOption();
    proxy.setGroupRetryTime(groupOption->group_retry_time);
    proxy.setAutoEjectGroupEnabled(groupOption->auto_eject_group);
    proxy.setEjectAfterRestoreEnabled(groupOption->eject_after_restore);
    proxy.setPassword(cfg->password());

    for (int i = 0; i < cfg->groupCnt(); ++i) {
        const CGroupInfo* info = cfg->group(i);

        RedisServantGroup* group = new RedisServantGroup;
        RedisServantGroupPolicy* policy = RedisServantGroupPolicy::createPolicy(info->groupPolicy());
        group->setGroupName(info->groupName());
        group->setPolicy(policy);

        const HostInfoList& hostList = info->hosts();
        HostInfoList::const_iterator itHost = hostList.begin();
        for (; itHost != hostList.end(); ++itHost) {
            const CHostInfo& hostInfo = (*itHost);
            RedisServant* servant = new RedisServant;
            RedisServant::Option opt;
            strcpy(opt.name, hostInfo.get_hostName().c_str());
            opt.poolSize = hostInfo.get_connectionNum();
            opt.reconnInterval = groupOption->backend_retry_interval;
            opt.maxReconnCount = groupOption->backend_retry_limit;
            servant->setOption(opt);
            servant->setRedisAddress(HostAddress(hostInfo.get_ip().c_str(), hostInfo.get_port()));
            servant->setEventLoop(proxy.eventLoop());
            if (hostInfo.get_master()) {
                group->addMasterRedisServant(servant);
            } else {
                group->addSlaveRedisServant(servant);
            }
            servant->connectionPool()->setPassword(itHost->passWord());
        }
        group->setEnabled(true);
        proxy.addRedisGroup(group);

        if (!twemproxyMode) {
            for (int i = info->hashMin(); i <= info->hashMax(); ++i) {
                proxy.setSlot(i, group);
            }

            for (int i = 0; i < cfg->hashMapCnt(); ++i) {
                const CHashMapping* mapping = cfg->hashMapping(i);
                RedisServantGroup* group = proxy.group(mapping->group_name);
                proxy.setSlot(mapping->hash_value, group);
            }
        } else {
            Slot* slot = proxy.slotData();
            for (int pointer_index = 1;
                    pointer_index <= points_per_server / pointer_per_hash;
                    pointer_index++) {

                char host[86];
                int hostlen = sprintf(host, "%s-%u", group->groupName(), pointer_index - 1);
                for (int x = 0; x < pointer_per_hash; x++) {
                    slot[slot_index].group = group;
                    slot[slot_index++].value = ketama_hash(host, hostlen, x);
                }
            }
        }
    }

    if (twemproxyMode) {
        LOG(Logger::Debug, "Twemproxy mode. dist=ketama slotcount=%d", proxy.slotCount());
        Slot* slot = proxy.slotData();
        int slotCount = proxy.slotCount();
        qsort(slot, slotCount, sizeof(Slot), slot_item_cmp);
    }

    HashFunc func = hashfuncFromName(cfg->hashFunctin().c_str());
    proxy.setHashFunction(func);

    for (int i = 0; i < cfg->keyMapCnt(); ++i) {
        const CKeyMapping* mapping = cfg->keyMapping(i);
        RedisServantGroup* group = proxy.group(mapping->group_name);
        if (group != NULL) {
            proxy.addGroupKeyMapping(mapping->key, strlen(mapping->key), group);
        }
    }

    LOG(Logger::Message, "Start the %s on port %d. PID: %d", APP_NAME, port, getpid());
    listenerLoop.exec();
}