Valkey 9.0源码剖析(2):服务器状态表示

Valkey服务器使用server.h/valkeyServer结构表示自身状态,这个结构包含了大量属性:

struct valkeyServer {
    // ...
}

Valkey根据各项属性的作用使用注释把它们分割成了多个部分,比如通用部分:

/* General */
pid_t pid;                /* Main process pid. */
pthread_t main_thread_id; /* Main thread id */
char *configfile;         /* Absolute config file path, or NULL */
char *executable;         /* Absolute executable file path. */
char **exec_argv;         /* Executable argv vector (copy). */
mode_t umask;             /* The umask value of the process on startup */
int hz;                   /* serverCron() calls frequency in hertz */
// ...

AOF持久化部分:

/* AOF persistence */
int aof_enabled;                    /* AOF configuration */
int aof_state;                      /* AOF_(ON|OFF|WAIT_REWRITE) */
int aof_fsync;                      /* Kind of fsync() policy */
char *aof_filename;                 /* Basename of the AOF file and manifest file */
char *aof_dirname;                  /* Name of the AOF directory */
// ...

RDB持久化部分:

/* RDB persistence */
long long dirty;                      /* Changes to DB from the last save */
long long dirty_before_bgsave;        /* Used to restore dirty on failed BGSAVE */
long long rdb_last_load_keys_expired; /* number of expired keys when loading RDB */
long long rdb_last_load_keys_loaded;  /* number of loaded keys when loading RDB */
struct saveparam *saveparams;         /* Save points array for RDB */
// ...

集群部分:

/* Cluster */
int cluster_enabled;                                   /* Is cluster enabled? */
int cluster_port;                                      /* Set the cluster port for a node. */
mstime_t cluster_node_timeout;                         /* Cluster node timeout. */
mstime_t cluster_ping_interval;                        /* A debug configuration for setting how often cluster nodes send ping messages. */
char *cluster_configfile;                              /* Cluster auto-generated config file name. */
struct clusterState *cluster;                          /* State of the cluster */
// ...

等等。

初始化常量属性

Valkey服务器使用server.c/initServerConfig()函数对valkeyServer结构中的常量属性进行初始化:

void initServerConfig(void) {
    int j;
    char *default_bindaddr[CONFIG_DEFAULT_BINDADDR_COUNT] = CONFIG_DEFAULT_BINDADDR;

    // 使用默认值初始化配置
    initConfigValues();
    updateCachedTime(1);
    server.cmd_time_snapshot = server.mstime;
    getRandomHexChars(server.runid, CONFIG_RUN_ID_SIZE);
    server.runid[CONFIG_RUN_ID_SIZE] = '\0';
    changeReplicationId();
    clearReplicationId2();
    server.hz = CONFIG_DEFAULT_HZ;   /* Initialize it ASAP, even if it may get
                                        updated later after loading the config.
                                        This value may be used before the server
                                        is initialized. */
    server.timezone = getTimeZone(); /* Initialized by tzset(). */
    server.configfile = NULL;
    server.executable = NULL;
    server.arch_bits = (sizeof(long) == 8) ? 64 : 32;
    server.bindaddr_count = CONFIG_DEFAULT_BINDADDR_COUNT;
    for (j = 0; j < CONFIG_DEFAULT_BINDADDR_COUNT; j++) server.bindaddr[j] = zstrdup(default_bindaddr[j]);
    memset(server.listeners, 0x00, sizeof(server.listeners));
    server.active_expire_enabled = 1;
    server.lazy_expire_disabled = 0;
    server.skip_checksum_validation = 0;
    // ...
}

可以看到,这个函数的主要作用就是对valkeyServer结构实例server变量的各项常量属性设置默认值。

初始化数据结构

在初始化服务器状态结构的常量属性,并载入启动服务器时给定的配置选项之后,服务器会调用server.c/initServer()函数,对服务器状态结构进行进一步的初始化,比如创建服务器所需的各项数据结构、创建服务器的输入和输出缓冲区、创建数据库数据结构等等:

void initServer(void) {
    signal(SIGHUP, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    setupSignalHandlers();
    ThreadsManager_init();
    makeThreadKillable();

    // ...

    /* Initialization after setting defaults from the config system. */
    server.aof_state = server.aof_enabled ? AOF_ON : AOF_OFF;
    server.fsynced_reploff = server.aof_enabled ? 0 : -1;
    server.in_fork_child = CHILD_TYPE_NONE;
    // ...
    server.clients = listCreate();
    server.clients_index = raxNew();
    server.clients_to_close = listCreate();
    server.replicas = listCreate();
    server.monitors = listCreate();
    server.replicas_waiting_psync = raxNew();
    server.wait_before_rdb_client_free = DEFAULT_WAIT_BEFORE_RDB_CLIENT_FREE;
    // ...

    // 创建共享对象
    createSharedObjects();
    adjustOpenFilesLimit();
    const char *clk_msg = monotonicInit();
    serverLog(LL_NOTICE, "monotonic clock: %s", clk_msg);

    // 创建服务器事件主循环状态
    server.el = aeCreateEventLoop(server.maxclients + CONFIG_FDSET_INCR);
    if (server.el == NULL) {
        serverLog(LL_WARNING, "Failed creating the event loop. Error message: '%s'", strerror(errno));
        exit(1);
    }

    // 创建数据库
    server.dbnum = server.cluster_enabled ? server.config_databases_cluster : server.config_databases;
    server.db = zcalloc(sizeof(serverDb *) * server.dbnum);
    createDatabaseIfNeeded(0); /* The default database should always exist */

    // ...
}
黄健宏
2025.12.23