redis学習ノート->時間イベント管理

4395 ワード

一、redisタイムキャッシュ
サーバ構造内には、2つのメンバーがあり、システムの現在の時間をキャッシュします.
redisServer
{
    time_t unixtime;        /* Unix time sampled every cron cycle. */
    long long mstime;       /* Like 'unixtime' but with milliseconds resolution. */
}
iniServer()関数を初期化し、システムタイミングでserverCron()関数を呼び出すと、updateCachedTime()がキャッシュを更新する時間が呼び出されます.
void updateCachedTime(void) {
    server.unixtime = time(NULL);
    server.mstime = mstime();
}

二、実行タイミングイベント
server構造体内にserverがある.hzメンバー、時間イベントserverCron()関数は呼び出しが終わるたびに1000/serverを返します.hz,タイムイベントプロセッサは,次のserverCron()関数をトリガする時点として,現在の時間にこの値を加算する.毎秒serverが呼び出されると思っていましたhz次serverCron()関数.
serverCron()関数では、クライアントのチェック、コマンド回数の統計など、いくつかのタイミングイベントが呼び出されます.1秒あたり1000/serverを実行する必要がないイベントもある.hz回なのでrun_を使う必要がありますwith_period(milliseconds)マクロは、milliseconds秒ごとにイベントを実行することを意味します.
#define run_with_period(_ms_) if ((_ms_ <= 1000/server.hz) || !(server.cronloops%((_ms_)/(1000/server.hz))))
//   100              
    run_with_period(100) trackOperationsPerSecond();
server.cronloopsはserverCron()関数が戻るたびに自動的に増加します.
三、タイミングイベント
クライアントの確認
    //      ,       ,            
    clientsCron();

void clientsCron(void) {

    //      
    int numclients = listLength(server.clients);

    //          
    int iterations = numclients/(server.hz*10);

    //       50     
    if (iterations < 50)
        iterations = (numclients < 50) ? numclients : 50;

    while(listLength(server.clients) && iterations--) {
        redisClient *c;
        listNode *head;

        /* Rotate the list, take the current head, process.
         * This way if the client must be removed from the list it's the
         * first element and we don't incur into O(N) computation. */
        //     ,        ,                    
        //   ,            ,              
        listRotate(server.clients);
        head = listFirst(server.clients);
        c = listNodeValue(head);
        /* The following functions do different service checks on the client.
         * The protocol is that they return non-zero if the client was
         * terminated. */
        //      ,           
        if (clientsCronHandleTimeout(c)) continue;
        //     ,             
        if (clientsCronResizeQueryBuffer(c)) continue;
    }
}

データベース操作
//            ,    ,         rehash
void databasesCron(void) {

    //              ,              

    /* Expire keys by random sampling. Not required for slaves
     * as master will synthesize DELs for us. */
    //            ,           
    if (server.active_expire_enabled && server.masterhost == NULL)
        //       CYCLE_SLOW ,             
        activeExpireCycle(ACTIVE_EXPIRE_CYCLE_SLOW);

    /* Perform hash tables rehashing if needed, but only if there are no
     * other processes saving the DB on disk. Otherwise rehashing is bad
     * as will cause a lot of copy-on-write of memory pages. */
    //     BGSAVE    BGREWRITEAOF    ,       rehash
    if (server.rdb_child_pid == -1 && server.aof_child_pid == -1) {
        /* We use global counters so if we stop the computation at a given
         * DB we'll be able to start from the successive in the next
         * cron loop iteration. */
        static unsigned int resize_db = 0;
        static unsigned int rehash_db = 0;
        unsigned int dbs_per_call = REDIS_DBCRON_DBS_PER_CALL;
        unsigned int j;

        /* Don't test more DBs than we have. */
        //            
        if (dbs_per_call > server.dbnum) dbs_per_call = server.dbnum;

        /* Resize */
        //        
        for (j = 0; j < dbs_per_call; j++) {
            tryResizeHashTables(resize_db % server.dbnum);
            resize_db++;
        }

        /* Rehash */
        //          rehash
        if (server.activerehashing) {
            for (j = 0; j < dbs_per_call; j++) {
                int work_done = incrementallyRehash(rehash_db % server.dbnum);
                rehash_db++;
                if (work_done) {
                    /* If the function did some work, stop here, we'll do
                     * more at the next cron loop. */
                    break;
                }
            }
        }
    }
}

タイミングログ、統計サーバコマンド、メモリ情報などもあります