• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase
您的位置:首页 > 数据库 >Redis > EasyCMS在幼儿园视频直播项目实战中以redis操作池的方式应对高并发的redis操作问题

EasyCMS在幼儿园视频直播项目实战中以redis操作池的方式应对高并发的redis操作问题

作者:Babosa的专栏 字体:[增加 减小] 来源:互联网 时间:2017-07-22

Babosa的专栏通过本文主要向大家介绍了EasyDarwin,redis操作池,幼儿园视频平台等相关知识,希望本文的分享对您有所帮助

在之前的博客《 EasyDarwin幼教云视频平台在幼教平台领域大放异彩!》中我们也介绍到,EasyCMS+EasyDarwin+redis形成的EasyDarwin云平台方案,在幼教平台领域中稳定运营,收到了用户的良好口碑;

随着幼儿园平台用户和接入幼儿园的数量不断增加,EasyCMS的redis操作也越来越频繁,我们在运维中发现EasyCMS的cpu占用非常高,通过线程分析,发现大家都在等待一个redis操作对象,redis操作对象锁造成了资源竞争,于是,我们决定采用redis操作池,我们的基本思路是:

  1. 初始化建立16个redis操作对象RedisHandler,并保持连接redis server;
  2. 采用链表的方式管理RedisHandler,先进先出的方式从链表获取RedisHandler;
  3. 当从链表获取不到RedisHandler,表示资源不足,动态new一个RedisHandler;
  4. 每一次操作Redis完成后,将RedisHandler插入回链表;
  5. 限定一个RedisHandler链表的最大长度,当超过最大长度时,直接对RedisHandler进行销毁,不插回链表;

基于这个思路,我们实现了一个RedisHandler类:

#ifndef __EASY_REDIS_HANDLER_H__
#define __EASY_REDIS_HANDLER_H__

#include "OSHeaders.h"
#include "QTSServerInterface.h"
#ifdef WIN32
#include "Windows/hiredis.h"
#else
#include "hiredis.h"
#endif //WIN32

#include "Task.h"

class RedisReplyObjectDeleter
{
    public:
        RedisReplyObjectDeleter() : fReply(NULL) {}
        explicit RedisReplyObjectDeleter(redisReply* reply) : fReply(reply)  {}
        ~RedisReplyObjectDeleter() 
        { 
            if (fReply)
            {
                freeReplyObject(fReply);
            }
        }

        void ClearObject() { fReply = NULL; }

        void SetObject(redisReply* reply) 
        {
            fReply = reply; 
        }
        redisReply* GetObject() const { return fReply; }

    private:

        redisReply* fReply;
};

class EasyRedisHandler : public Task
{
public:

    EasyRedisHandler(const char* ip, UInt16 port, const char* passwd);
    virtual ~EasyRedisHandler();

    QTSS_Error RedisTTL();

    QTSS_Error RedisSetDevice(Easy_DeviceInfo_Params* inParams);
    QTSS_Error RedisDelDevice(Easy_DeviceInfo_Params* inParams);
    QTSS_Error RedisGetAssociatedDarwin(QTSS_GetAssociatedDarwin_Params* inParams);

    OSQueueElem     fQueueElem; 
    UInt32          fID;
private:

    virtual SInt64  Run();

    bool            sIfConSucess;
    OSMutex         sMutex;
    redisContext*   redisContext_;


    char            fRedisIP[128];
    UInt16          fRedisPort;
    char            fRedisPasswd[256];

    bool RedisConnect();
    void RedisErrorHandler();
};



#endif //__EASY_REDIS_HANDLER_H__
#include "EasyRedisHandler.h"

#include "QTSSMemoryDeleter.h"
#include "Format.h"
#include "Resources.h"

static UInt32 sRedisHandlerID = 0;

EasyRedisHandler::EasyRedisHandler(const char* ip, UInt16 port, const char* passwd)
    : fQueueElem(),
    fID(sRedisHandlerID++),
    sIfConSucess(false),
    sMutex(),
    redisContext_(NULL)
{
    this->SetTaskName("EasyRedisHandler");

    fQueueElem.SetEnclosingObject(this);

    ::strcpy(fRedisIP, ip);
    fRedisPort = port;
    ::strcpy(fRedisPasswd, passwd);

    this->Signal(Task::kStartEvent);
}

EasyRedisHandler::~EasyRedisHandler()
{
    RedisErrorHandler();
}

SInt64 EasyRedisHandler::Run()
{
    OSMutexLocker locker(&sMutex);

    EventFlags theEvents = this->GetEvents();

    RedisConnect();

    return 0;
}

bool EasyRedisHandler::RedisConnect()
{
    if (sIfConSucess)
    {
        return true;
    }

    bool theRet = false;
    do
    {
        struct timeval timeout = { 2, 0 }; // 2 seconds
        redisContext_ = redisConnectWithTimeout(fRedisIP, fRedisPort, timeout);
        if (!redisContext_ || redisContext_->err)
        {
            if (redisContext_)
            {
                printf("Redis context connect error \n");
            }
            else
            {
                printf("Connection error: can't allocate redis context\n");
            }

            theRet = false;
            break;
        }

        string auth = Format("auth %s", string(fRedisPasswd));
        redisReply* reply = static_cast<redisReply*>(redisCommand(redisContext_, auth.c_str()));

        RedisReplyObjectDeleter replyDeleter(reply);
        if (!reply || string(reply->str) != string("OK"))
        {
            printf("Redis auth error\n");
            theRet = false;
            break;
        }

        theRet = true;
        sIfConSucess = true;

        printf(
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • EasyCMS在幼儿园视频直播项目实战中以redis操作池的方式应对高并发的redis操作问题

相关文章

  • 2017-05-11Redis批量删除KEY的方法
  • 2017-05-11Redis中五种数据类型简单操作
  • 2017-05-11在Redis数据库中实现分布式速率限制的方法
  • 2017-05-11Redis正确使用的十个技巧
  • 2017-05-11Redis教程(十二):服务器管理命令总结
  • 2017-05-11图文详解Windows下使用Redis缓存工具的方法
  • 2017-05-11在redhat6.4安装redis集群【教程】
  • 2017-05-11在CentOS 7环境下安装Redis数据库详解
  • 2017-05-11Redis的LRU机制介绍
  • 2017-05-11php结合redis实现高并发下的抢购、秒杀功能的实例

文章分类

  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase

最近更新的内容

    • CentOS系统下Redis安装和自启动配置的步骤
    • 详解使用Redis SETNX 命令实现分布式锁
    • Redis2.8配置文件中文详解
    • Redis系列(四)--内存淘汰机制(含单机版内存优化建议)
    • 浅谈redis采用不同内存分配器tcmalloc和jemalloc
    • 详解Redis用链表实现消息队列
    • php结合redis实现高并发下的抢购、秒杀功能的实例
    • Redis简介
    • 利用yum安装Redis的方法详解
    • 关于redis Key淘汰策略的实现方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有