{"id":363,"date":"2019-10-26T21:52:08","date_gmt":"2019-10-26T13:52:08","guid":{"rendered":"https:\/\/www.ccagml.com\/?p=363"},"modified":"2021-04-27T21:16:22","modified_gmt":"2021-04-27T13:16:22","slug":"redis%e6%ba%90%e7%a0%81%e4%bb%8emain%e5%bc%80%e5%a7%8b2","status":"publish","type":"post","link":"https:\/\/www.ccagml.com\/?p=363","title":{"rendered":"redis\u6e90\u7801\u4ecemain\u5f00\u59cb2"},"content":{"rendered":"\n<ul><li><a href=\"https:\/\/www.ccagml.com\/?p=357\">redis\u6e90\u7801\u4ecemain\u5f00\u59cb1<\/a>\u4e2dinitServerConfig\u65b9\u6cd5\u521d\u59cb\u5316\u914d\u7f6e\uff0c\u5728\u8fd9\u4e4b\u540e\uff0cinitServer\u65b9\u6cd5\u6839\u636e\u914d\u7f6e\u521b\u5efaredis\u6240\u9700\u8981\u7684\u76f8\u5173\u5185\u5bb9\uff0c\u521b\u5efa\u76d1\u542c\u7aef\u53e3\u7b49\u76f8\u5173\u64cd\u4f5c<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>\nvoid initServer()\n{\n    int j;\n\n    \/\/ \u8bbe\u7f6e\u4fe1\u53f7\u5904\u7406\u51fd\u6570\n    signal(SIGHUP, SIG_IGN);\n    signal(SIGPIPE, SIG_IGN);\n    setupSignalHandlers();\n\n    \/\/ \u8bbe\u7f6e syslog\n    if (server.syslog_enabled)\n    {\n        openlog(server.syslog_ident, LOG_PID | LOG_NDELAY | LOG_NOWAIT,\n                server.syslog_facility);\n    }\n    \/\/ \u521d\u59cb\u5316\u5e76\u521b\u5efa\u6570\u636e\u7ed3\u6784\n    server.current_client = NULL;\n    server.clients = listCreate(); \/\/ \u4e00\u4e2a\u94fe\u8868\uff0c\u4fdd\u5b58\u4e86\u6240\u6709\u5ba2\u6237\u7aef\u72b6\u6001\u7ed3\u6784\n    server.clients_to_close = listCreate(); \/\/ \u94fe\u8868\uff0c\u4fdd\u5b58\u4e86\u6240\u6709\u5f85\u5173\u95ed\u7684\u5ba2\u6237\u7aef\n    server.slaves = listCreate();           \/\/ \u94fe\u8868\uff0c\u4fdd\u5b58\u4e86\u6240\u6709\u4ece\u670d\u52a1\u5668\n    server.monitors = listCreate();         \/\/ \u94fe\u8868\uff0c\u4fdd\u5b58\u4e86\u6240\u6709\u76d1\u89c6\u5668\n    server.slaveseldb = -1; \/* Force to emit the first SELECT command. *\/\n    server.unblocked_clients = listCreate(); \/\/ \u53d6\u6d88\u6240\u6709\u5728 unblocked_clients \u94fe\u8868\u4e2d\u7684\u5ba2\u6237\u7aef\u7684\u963b\u585e\u72b6\u6001\n    server.ready_keys = listCreate();        \/\/  If the specified key has clients blocked waiting for list pushes, this* function will put the key reference into the server.ready_keys list.\n    server.clients_waiting_acks = listCreate(); \/\/ \u7b49\u5f85\u547d\u4ee4\u8fd4\u56de\u7684\u5ba2\u6237\u7aef\n    server.get_ack_from_slaves = 0;             \/* If true we send REPLCONF GETACK. *\/\n    server.clients_paused = 0;                  \/* True if clients are currently paused *\/\n\n    \/\/ \u521b\u5efa\u5171\u4eab\u5bf9\u8c61 \u901a\u8fc7\u590d\u7528\u6765\u51cf\u5c11\u5185\u5b58\u788e\u7247\uff0c\u4ee5\u53ca\u51cf\u5c11\u64cd\u4f5c\u8017\u65f6\u7684\u5171\u4eab\u5bf9\u8c61\n    createSharedObjects();\n    adjustOpenFilesLimit();                                                         \/\/ \u68c0\u67e5\u6587\u4ef6\u6253\u5f00\u6570\u591f\u4e0d\u591f\n    server.el = aeCreateEventLoop(server.maxclients + REDIS_EVENTLOOP_FDSET_INCR);  \/\/\u521b\u5efa\u4e8b\u4ef6\u5faa\u73af\n    server.db = zmalloc(sizeof(redisDb) * server.dbnum);\n\n    \/* Open the TCP listening socket for the user commands. *\/\n    \/\/ \u6253\u5f00 TCP \u76d1\u542c\u7aef\u53e3\uff0c\u7528\u4e8e\u7b49\u5f85\u5ba2\u6237\u7aef\u7684\u547d\u4ee4\u8bf7\u6c42\n    if (server.port != 0 &amp;&amp;\n        listenToPort(server.port, server.ipfd, &amp;server.ipfd_count) == REDIS_ERR)\n        exit(1);\n\n    \/* Open the listening Unix domain socket. *\/\n    \/\/ \u6253\u5f00 UNIX \u672c\u5730\u7aef\u53e3\n    if (server.unixsocket != NULL)\n    {\n        unlink(server.unixsocket); \/* don't care if this fails *\/\n        server.sofd = anetUnixServer(server.neterr, server.unixsocket,\n                                     server.unixsocketperm, server.tcp_backlog);\n        if (server.sofd == ANET_ERR)\n        {\n            redisLog(REDIS_WARNING, \"Opening socket: %s\", server.neterr);\n            exit(1);\n        }\n        anetNonBlock(NULL, server.sofd);\n    }\n\n    \/* Abort if there are no listening sockets at all. *\/\n    if (server.ipfd_count == 0 &amp;&amp; server.sofd &lt; 0)\n    {\n        redisLog(REDIS_WARNING, \"Configured to not listen anywhere, exiting.\");\n        exit(1);\n    }\n\n    \/* Create the Redis databases, and initialize other internal state. *\/\n    \/\/ \u521b\u5efa\u5e76\u521d\u59cb\u5316\u6570\u636e\u5e93\u7ed3\u6784\n    for (j = 0; j &lt; server.dbnum; j++)\n    {\n        server.db[j].dict = dictCreate(&amp;dbDictType, NULL);\n        server.db[j].expires = dictCreate(&amp;keyptrDictType, NULL);\n        server.db[j].blocking_keys = dictCreate(&amp;keylistDictType, NULL);\n        server.db[j].ready_keys = dictCreate(&amp;setDictType, NULL);\n        server.db[j].watched_keys = dictCreate(&amp;keylistDictType, NULL);\n        server.db[j].eviction_pool = evictionPoolAlloc();\n        server.db[j].id = j;\n        server.db[j].avg_ttl = 0;\n    }\n\n    \/\/ \u521b\u5efa PUBSUB \u76f8\u5173\u7ed3\u6784\n    server.pubsub_channels = dictCreate(&amp;keylistDictType, NULL);\n    server.pubsub_patterns = listCreate();\n    listSetFreeMethod(server.pubsub_patterns, freePubsubPattern);\n    listSetMatchMethod(server.pubsub_patterns, listMatchPubsubPattern);\n\n    server.cronloops = 0; \/\/ \/* Number of times the cron function run *\/\n    server.rdb_child_pid = -1; \/* PID of RDB saving child *\/\n    server.aof_child_pid = -1; \/* PID if rewriting process *\/\n    aofRewriteBufferReset();\n    server.aof_buf = sdsempty();\n    server.lastsave = time(NULL); \/* At startup we consider the DB saved. *\/\n    server.lastbgsave_try = 0;    \/* At startup we never tried to BGSAVE. *\/\n    server.rdb_save_time_last = -1;\n    server.rdb_save_time_start = -1;\n    server.dirty = 0;\n    resetServerStats();\n    \/* A few stats we don't want to reset: server startup time, and peak mem. *\/\n    server.stat_starttime = time(NULL); \/* Server start time *\/\n    server.stat_peak_memory = 0;        \/* Max used memory record *\/\n    server.resident_set_size = 0;       \/* RSS sampled in serverCron(). *\/\n    server.lastbgsave_status = REDIS_OK;\n    server.aof_last_write_status = REDIS_OK;\n    server.aof_last_write_errno = 0;\n    server.repl_good_slaves_count = 0;\n    updateCachedTime();\n\n    \/* Create the serverCron() time event, that's our main way to process\n     * background operations. *\/\n    \/\/ \u4e3a serverCron() \u521b\u5efa\u65f6\u95f4\u4e8b\u4ef6\n    if (aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL) == AE_ERR)\n    {\n        redisPanic(\"Can't create the serverCron time event.\");\n        exit(1);\n    }\n\n    \/* Create an event handler for accepting new connections in TCP and Unix\n     * domain sockets. *\/\n    \/\/ \u4e3a TCP \u8fde\u63a5\u5173\u8054\u8fde\u63a5\u5e94\u7b54\uff08accept\uff09\u5904\u7406\u5668\n    \/\/ \u7528\u4e8e\u63a5\u53d7\u5e76\u5e94\u7b54\u5ba2\u6237\u7aef\u7684 connect() \u8c03\u7528\n    for (j = 0; j &lt; server.ipfd_count; j++)\n    {\n        if (aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE,\n                              acceptTcpHandler, NULL) == AE_ERR)\n        {\n            redisPanic(\n                \"Unrecoverable error creating server.ipfd file event.\");\n        }\n    }\n\n    \/\/ \u4e3a\u672c\u5730\u5957\u63a5\u5b57\u5173\u8054\u5e94\u7b54\u5904\u7406\u5668\n    if (server.sofd > 0 &amp;&amp; aeCreateFileEvent(server.el, server.sofd, AE_READABLE,\n                                             acceptUnixHandler, NULL) == AE_ERR)\n        redisPanic(\"Unrecoverable error creating server.sofd file event.\");\n\n    \/* Open the AOF file if needed. *\/\n    \/\/ \u5982\u679c AOF \u6301\u4e45\u5316\u529f\u80fd\u5df2\u7ecf\u6253\u5f00\uff0c\u90a3\u4e48\u6253\u5f00\u6216\u521b\u5efa\u4e00\u4e2a AOF \u6587\u4ef6\n    if (server.aof_state == REDIS_AOF_ON)\n    {\n        server.aof_fd = open(server.aof_filename,\n                             O_WRONLY | O_APPEND | O_CREAT, 0644);\n        if (server.aof_fd == -1)\n        {\n            redisLog(REDIS_WARNING, \"Can't open the append-only file: %s\",\n                     strerror(errno));\n            exit(1);\n        }\n    }\n\n    \/* 32 bit instances are limited to 4GB of address space, so if there is\n     * no explicit limit in the user provided configuration we set a limit\n     * at 3 GB using maxmemory with 'noeviction' policy'. This avoids\n     * useless crashes of the Redis instance for out of memory. *\/\n    \/\/ \u5bf9\u4e8e 32 \u4f4d\u5b9e\u4f8b\u6765\u8bf4\uff0c\u9ed8\u8ba4\u5c06\u6700\u5927\u53ef\u7528\u5185\u5b58\u9650\u5236\u5728 3 GB\n    if (server.arch_bits == 32 &amp;&amp; server.maxmemory == 0)\n    {\n        redisLog(REDIS_WARNING, \"Warning: 32 bit instance detected but no memory limit set. Setting 3 GB maxmemory limit with 'noeviction' policy now.\");\n        server.maxmemory = 3072LL * (1024 * 1024); \/* 3 GB *\/\n        server.maxmemory_policy = REDIS_MAXMEMORY_NO_EVICTION;\n    }\n\n    \/\/ \u5982\u679c\u670d\u52a1\u5668\u4ee5 cluster \u6a21\u5f0f\u6253\u5f00\uff0c\u90a3\u4e48\u521d\u59cb\u5316 cluster\n    if (server.cluster_enabled)\n        clusterInit();\n\n    \/\/ \u521d\u59cb\u5316\u590d\u5236\u529f\u80fd\u6709\u5173\u7684\u811a\u672c\u7f13\u5b58\n    replicationScriptCacheInit();\n\n    \/\/ \u521d\u59cb\u5316\u811a\u672c\u7cfb\u7edf\n    scriptingInit();\n\n    \/\/ \u521d\u59cb\u5316\u6162\u67e5\u8be2\u529f\u80fd\n    slowlogInit();\n\n    \/\/ \u521d\u59cb\u5316 BIO \u7cfb\u7edf\n    bioInit();\n}\n\n\nint listenToPort(int port, int *fds, int *count)\n{\n    int j;\n\n    \/* Force binding of 0.0.0.0 if no bind address is specified, always\n     * entering the loop if j == 0. *\/\n    if (server.bindaddr_count == 0)\n        server.bindaddr[0] = NULL;\n    for (j = 0; j &lt; server.bindaddr_count || j == 0; j++)\n    {\n        if (server.bindaddr[j] == NULL)\n        {\n            \/* Bind * for both IPv6 and IPv4, we enter here only if\n             * server.bindaddr_count == 0. *\/\n            fds[*count] = anetTcp6Server(server.neterr, port, NULL,\n                                         server.tcp_backlog);\n            if (fds[*count] != ANET_ERR)\n            {\n                anetNonBlock(NULL, fds[*count]);\n                (*count)++;\n            }\n            \/\/ \u63a5\u6536\u76d1\u542c\n            fds[*count] = anetTcpServer(server.neterr, port, NULL,\n                                        server.tcp_backlog);\n            if (fds[*count] != ANET_ERR)\n            {\n                anetNonBlock(NULL, fds[*count]);\n                (*count)++;\n            }\n            \/* Exit the loop if we were able to bind * on IPv4 or IPv6,\n             * otherwise fds[*count] will be ANET_ERR and we'll print an\n             * error and return to the caller with an error. *\/\n            if (*count)\n                break;\n        }\n        else if (strchr(server.bindaddr[j], ':'))\n        {\n            \/* Bind IPv6 address. *\/\n            fds[*count] = anetTcp6Server(server.neterr, port, server.bindaddr[j],\n                                         server.tcp_backlog);\n        }\n        else\n        {\n            \/* Bind IPv4 address. *\/\n            fds[*count] = anetTcpServer(server.neterr, port, server.bindaddr[j],\n                                        server.tcp_backlog);\n        }\n        if (fds[*count] == ANET_ERR)\n        {\n            redisLog(REDIS_WARNING,\n                     \"Creating Server TCP listening socket %s:%d: %s\",\n                     server.bindaddr[j] ? server.bindaddr[j] : \"*\",\n                     port, server.neterr);\n            return REDIS_ERR;\n        }\n        anetNonBlock(NULL, fds[*count]);\n        (*count)++;\n    }\n    return REDIS_OK;\n}\n\n\n\/\/ipv4\u5f00\u59cb\u76d1\u542c, \u8fd4\u56desocket\u76d1\u542c\u7684fd\nstatic int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backlog)\n{\n    int s, rv;\n    char _port[6]; \/* strlen(\"65535\") *\/\n    struct addrinfo hints, *servinfo, *p;\n\n    snprintf(_port, 6, \"%d\", port);\n    memset(&amp;hints, 0, sizeof(hints));\n    hints.ai_family = af;\n    hints.ai_socktype = SOCK_STREAM;\n    hints.ai_flags = AI_PASSIVE; \/* No effect if bindaddr != NULL *\/\n\n    if ((rv = getaddrinfo(bindaddr, _port, &amp;hints, &amp;servinfo)) != 0)\n    {\n        anetSetError(err, \"%s\", gai_strerror(rv));\n        return ANET_ERR;\n    }\n    for (p = servinfo; p != NULL; p = p->ai_next)\n    {\n        if ((s = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)\n            continue;\n\n        if (af == AF_INET6 &amp;&amp; anetV6Only(err, s) == ANET_ERR)\n            goto error;\n        if (anetSetReuseAddr(err, s) == ANET_ERR)\n            goto error;\n        if (anetListen(err, s, p->ai_addr, p->ai_addrlen, backlog) == ANET_ERR)\n            goto error;\n        goto end;\n    }\n    if (p == NULL)\n    {\n        anetSetError(err, \"unable to bind socket\");\n        goto error;\n    }\n\nerror:\n    s = ANET_ERR;\nend:\n    freeaddrinfo(servinfo);\n    return s;\n}\n\nint anetTcpServer(char *err, int port, char *bindaddr, int backlog)\n{\n    return _anetTcpServer(err, port, bindaddr, AF_INET, backlog);\n}\n<\/code><\/pre>\n\n\n\n<p><a href=\"https:\/\/download.redis.io\/releases\/redis-3.0.0.tar.gz\" target=\"_blank\" rel=\"noopener\">\u57fa\u4e8e\u7248\u672c3.0.0\u7248\u672c,<\/a>\u70b9\u51fb\u4e0b\u8f7dhttps:\/\/download.redis.io\/releases\/redis-3.0.0.tar.gz<\/p>\n\n\n\n<p><a href=\"https:\/\/www.ccagml.com\/?p=363\">\u672c\u6587\u5730\u5740<\/a>\uff0chttps:\/\/www.ccagml.com\/?p=363<\/p>\n","protected":false},"excerpt":{"rendered":"<p>redis\u6e90\u7801\u4ecemain\u5f00\u59cb1\u4e2dinitServerConfig\u65b9\u6cd5\u521d\u59cb\u5316\u914d\u7f6e\uff0c\u5728\u8fd9\u4e4b\u540e\uff0cinitServer<a href=\"https:\/\/www.ccagml.com\/?p=363\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">redis\u6e90\u7801\u4ecemain\u5f00\u59cb2<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[31,22],"tags":[],"_links":{"self":[{"href":"https:\/\/www.ccagml.com\/index.php?rest_route=\/wp\/v2\/posts\/363"}],"collection":[{"href":"https:\/\/www.ccagml.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ccagml.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ccagml.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ccagml.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=363"}],"version-history":[{"count":6,"href":"https:\/\/www.ccagml.com\/index.php?rest_route=\/wp\/v2\/posts\/363\/revisions"}],"predecessor-version":[{"id":373,"href":"https:\/\/www.ccagml.com\/index.php?rest_route=\/wp\/v2\/posts\/363\/revisions\/373"}],"wp:attachment":[{"href":"https:\/\/www.ccagml.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=363"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ccagml.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=363"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ccagml.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=363"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}