{"id":65929,"date":"2026-01-25T22:16:55","date_gmt":"2026-01-25T14:16:55","guid":{"rendered":"https:\/\/www.wsisp.com\/helps\/65929.html"},"modified":"2026-01-25T22:16:55","modified_gmt":"2026-01-25T14:16:55","slug":"%e4%b8%87%e5%ad%97%e9%95%bf%e6%96%87%e8%a7%a3%e6%9e%90%ef%bc%9aredis-8-4-%e7%bd%91%e7%bb%9c-io-%e6%9e%b6%e6%9e%84%e6%b7%b1%e5%ba%a6%e6%8b%86%e8%a7%a3","status":"publish","type":"post","link":"https:\/\/www.wsisp.com\/helps\/65929.html","title":{"rendered":"\u4e07\u5b57\u957f\u6587\u89e3\u6790\uff1aRedis 8.4 \u7f51\u7edc IO \u67b6\u6784\u6df1\u5ea6\u62c6\u89e3"},"content":{"rendered":"<h2>\u7b2c\u4e00\u90e8\u5206&#xff1a;Redis 8.4 \u7f51\u7edc\u6a21\u578b\u5b8f\u89c2\u67b6\u6784\u4e0e\u6e90\u7801\u5165\u53e3<\/h2>\n<p>\u5e74\u524d\u8fd9\u6bb5\u65f6\u95f4\u8d4b\u95f2\u5728\u5bb6&#xff0c;\u6211\u7cfb\u7edf\u6574\u7406\u4e86 10 \u7bc7\u6df1\u5ea6\u89e3\u6790 Go \u8bed\u8a00\u7684\u786c\u6838\u6587\u7ae0&#xff0c;\u968f\u540e\u53c8\u7cbe\u9009\u4e86 10 \u7bc7\u5f53\u4e0b\u70ed\u95e8 AI \u5927\u6a21\u578b\u7684\u6280\u672f\u6587\u7ae0&#xff08;Token\u3001MCP\u3001Agent\u3001Skills\u3001Vibe Coding \u7b49&#xff09;\u3002\u4eca\u5929&#xff0c;\u6211\u5c06\u89c6\u89d2\u8f6c\u5411 Redis&#xff0c;\u4ece\u6e90\u7801\u5c42\u9762\u6df1\u5165\u5256\u6790\u5b83\u7684\u7f51\u7edc\u6a21\u578b\u5b9e\u73b0&#xff0c;\u82e5\u5bf9 Redis \u6570\u636e\u7ed3\u6784\u611f\u5174\u8da3&#xff0c;\u4e5f\u53ef\u4ee5\u770b\u770b\u6211\u8fd9\u4e2a Redis \u4e13\u680f&#xff0c;\u5176\u4e2d\u8be6\u7ec6\u5256\u6790\u4e86\u5e38\u89c1\u7684\u529f\u80fd\u5b9e\u73b0\u673a\u5236\u3002<\/p>\n<p>Redis 8.4 \u7684\u9ad8\u6027\u80fd\u672c\u8d28\u4e0a\u4ecd\u7136\u5efa\u7acb\u5728 I\/O \u591a\u8def\u590d\u7528\u4e0e\u975e\u963b\u585e I\/O \u4e4b\u4e0a\u7684 Reactor \u6a21\u578b&#xff1a;\u6240\u6709\u547d\u4ee4\u7684\u89e3\u6790\u4e0e\u6267\u884c\u59cb\u7ec8\u7531\u4e3b\u7ebf\u7a0b\u4ee5\u5355\u7ebf\u7a0b\u65b9\u5f0f\u987a\u5e8f\u5b8c\u6210&#xff0c;\u4ee5\u4fdd\u8bc1\u65e0\u9501\u4e0e\u5f3a\u4e00\u81f4\u6027&#xff1b;\u591a\u7ebf\u7a0b\u4ec5\u53c2\u4e0e\u547d\u4ee4\u6267\u884c\u8def\u5f84\u4e4b\u5916\u7684\u7f51\u7edc I\/O \u4e0e\u6570\u636e\u642c\u8fd0\u7b49\u8f85\u52a9\u9636\u6bb5&#xff0c;\u7528\u4e8e\u7f13\u89e3 I\/O \u5bc6\u96c6\u573a\u666f\u4e0b\u7684\u6027\u80fd\u74f6\u9888&#xff0c;\u800c\u4e0d\u5f15\u5165\u547d\u4ee4\u7ea7\u5e76\u53d1\u3002\u5728\u6b64\u57fa\u7840\u4e0a&#xff0c;8.x \u7248\u672c\u8fdb\u4e00\u6b65\u91cd\u6784\u4e86\u7f51\u7edc\u5c42&#xff0c;\u5f15\u5165\u66f4\u6e05\u6670\u7684 connection \u62bd\u8c61\u4e0e privdata \u673a\u5236&#xff0c;\u5b9e\u73b0\u4e8b\u4ef6\u5e93\u4e0e\u4e1a\u52a1\u903b\u8f91\u7684\u66f4\u5f7b\u5e95\u89e3\u8026\u3002<\/p>\n<h3>1.1 \u80cc\u666f&#xff1a;\u4ece\u201c\u534f\u8bae\u98ce\u6ce2\u201d\u5230\u201c\u521b\u59cb\u56de\u5f52\u201d\u7684 8.x \u65f6\u4ee3<\/h3>\n<p>\u5206\u6790 Redis 8.4 \u7684\u6e90\u7801\u4e4b\u524d&#xff0c;\u5fc5\u987b\u7406\u89e3\u5b83\u6240\u5904\u7684\u7279\u6b8a\u5386\u53f2\u8282\u70b9\u30022024 \u5e74\u521d&#xff0c;Redis \u5b98\u65b9\u5ba3\u5e03\u5c06\u5176\u5f00\u6e90\u534f\u8bae\u4ece BSD \u53d8\u66f4\u4e3a RSALv2\/SSPLv1&#xff0c;\u8fd9\u4e00\u4e3e\u52a8\u5f15\u53d1\u4e86\u5f00\u6e90\u793e\u533a\u7684\u5de8\u5927\u9707\u52a8&#xff0c;\u968f\u540e\u8bde\u751f\u4e86 Valkey\u3001Redict \u7b49\u91cd\u8981\u5206\u652f\u3002<\/p>\n<p>\u5c31\u5728\u793e\u533a\u5206\u88c2\u7684\u9634\u973e\u4e0b&#xff0c;Redis \u4e4b\u7236 Salvatore Sanfilippo&#xff08;antirez&#xff09;\u4ee5\u6280\u672f\u987e\u95ee\u7684\u8eab\u4efd\u91cd\u65b0\u56de\u5f52\u793e\u533a&#xff0c;\u5e76\u53c2\u4e0e\u5230\u4e86 Redis 8.0 \u8fd9\u4e00\u91cc\u7a0b\u7891\u7248\u672c\u7684\u67b6\u6784\u8bbe\u8ba1\u4e2d\u3002Redis 8.4 \u6b63\u662f\u8fd9\u4e00\u201c\u6587\u827a\u590d\u5174\u201d\u65f6\u671f\u7684\u4ea7\u7269\u3002\u4e3a\u4e86\u5e94\u5bf9\u6765\u81ea\u793e\u533a\u5206\u652f\u7684\u7ade\u4e89&#xff0c;8.4 \u7248\u672c\u5728\u6027\u80fd\u4f18\u5316\u548c\u4ee3\u7801\u6a21\u5757\u5316\u4e0a\u505a\u4e86\u6781\u5927\u7684\u6539\u8fdb&#xff0c;\u4f8b\u5982\u6211\u4eec\u5373\u5c06\u5728\u6e90\u7801\u4e2d\u770b\u5230\u7684 aeEventLoop \u7684\u91cd\u6784&#xff0c;\u5c31\u662f\u4e3a\u4e86\u8ba9 Redis \u6838\u5fc3\u903b\u8f91\u66f4\u52a0\u89e3\u8026\u3001\u66f4\u6613\u4e8e\u6d4b\u8bd5\u548c\u6269\u5c55\u3002<\/p>\n<h3>1.2 \u6838\u5fc3\u6e90\u7801\u6587\u4ef6\u5730\u56fe<\/h3>\n<p>\u5728 Redis 8.4 \u7684 src \u76ee\u5f55\u4e0b&#xff0c;\u7f51\u7edc\u6a21\u578b\u7684\u6838\u5fc3\u903b\u8f91\u5206\u5e03\u5728\u4ee5\u4e0b\u6587\u4ef6&#xff1a;<\/p>\n<ul>\n<li>ae.c \/ ae.h&#xff1a;\u4e8b\u4ef6\u9a71\u52a8\u6846\u67b6\u3002\u5c01\u88c5\u4e86 epoll\u3001kqueue \u7b49&#xff0c;\u63d0\u4f9b\u7edf\u4e00\u7684\u4e8b\u4ef6\u5faa\u73af\u63a5\u53e3\u3002<\/li>\n<li>ae_epoll.c&#xff1a;Linux \u73af\u5883\u4e0b\u5177\u4f53\u7684 I\/O \u591a\u8def\u590d\u7528\u5b9e\u73b0&#xff0c;\u76f4\u63a5\u5c01\u88c5 epoll_wait\u3002<\/li>\n<li>networking.c&#xff1a;\u5ba2\u6237\u7aef\u8fde\u63a5\u7ba1\u7406\u3001\u8bfb\u5199\u7f13\u51b2\u533a\u64cd\u4f5c\u3001\u591a\u7ebf\u7a0b I\/O \u7684\u4efb\u52a1\u5206\u53d1\u3002<\/li>\n<li>connection.c \/ connection.h&#xff1a;\u8fde\u63a5\u5c42\u62bd\u8c61\u3002\u5c06 TCP\u3001TLS\u3001Unix Socket \u7edf\u4e00\u62bd\u8c61\u4e3a connection \u5bf9\u8c61\u3002<\/li>\n<li>resp_parser.c&#xff1a;Redis \u534f\u8bae&#xff08;RESP2\/3&#xff09;\u89e3\u6790\u5668\u7684\u6838\u5fc3\u5b9e\u73b0\u3002<\/li>\n<li>server.c&#xff1a;\u4e3b\u7a0b\u5e8f\u5165\u53e3&#xff0c;\u8d1f\u8d23\u8c03\u7528 initServer \u8fdb\u884c\u7f51\u7edc\u521d\u59cb\u5316\u5e76\u542f\u52a8\u4e8b\u4ef6\u5faa\u73af\u3002<\/li>\n<li>anet.c&#xff1a;\u5e95\u5c42\u7684\u7f51\u7edc\u539f\u8bed\u5c01\u88c5&#xff0c;\u5982 TCP_NODELAY \u8bbe\u7f6e\u3001Socket \u521b\u5efa\u7b49\u3002<\/li>\n<\/ul>\n<h3>1.3 \u6838\u5fc3\u6570\u636e\u7ed3\u6784&#xff1a;aeEventLoop \u4e0e client<\/h3>\n<h4>1.3.1 \u4e8b\u4ef6\u5faa\u73af\u7ed3\u6784\u4f53 aeEventLoop<\/h4>\n<p>\u5728 Redis 8.4 \u7684 ae.h \u4e2d&#xff0c;aeEventLoop \u662f\u6574\u4e2a\u7f51\u7edc\u6a21\u578b\u7684\u6838\u5fc3\u3002\u76f8\u6bd4\u65e9\u671f\u7248\u672c&#xff0c;\u5b83\u901a\u8fc7 privdata[2] \u589e\u5f3a\u4e86\u4e0a\u4e0b\u6587\u4f20\u9012\u80fd\u529b\u3002<\/p>\n<p><span class=\"token comment\">\/* \u6e90\u7801\u4f4d\u7f6e: src\/ae.h *\/<\/span><br \/>\n<span class=\"token keyword\">typedef<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">aeEventLoop<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> maxfd<span class=\"token punctuation\">;<\/span>               <span class=\"token comment\">\/* \u5f53\u524d\u6ce8\u518c\u7684\u6700\u5927\u6587\u4ef6\u63cf\u8ff0\u7b26 *\/<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> setsize<span class=\"token punctuation\">;<\/span>             <span class=\"token comment\">\/* \u76d1\u63a7\u7684\u6700\u5927 FD \u6570\u91cf\u9650\u5236 *\/<\/span><br \/>\n    <span class=\"token keyword\">long<\/span> <span class=\"token keyword\">long<\/span> timeEventNextId<span class=\"token punctuation\">;<\/span><br \/>\n    aeFileEvent <span class=\"token operator\">*<\/span>events<span class=\"token punctuation\">;<\/span>     <span class=\"token comment\">\/* \u6ce8\u518c\u7684\u6587\u4ef6\u4e8b\u4ef6&#xff08;\u6570\u7ec4\u5927\u5c0f\u4e3a setsize&#xff09; *\/<\/span><br \/>\n    aeFiredEvent <span class=\"token operator\">*<\/span>fired<span class=\"token punctuation\">;<\/span>     <span class=\"token comment\">\/* \u5c31\u7eea\u7684\u6587\u4ef6\u4e8b\u4ef6 *\/<\/span><br \/>\n    aeTimeEvent <span class=\"token operator\">*<\/span>timeEventHead<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> stop<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">void<\/span> <span class=\"token operator\">*<\/span>apidata<span class=\"token punctuation\">;<\/span>           <span class=\"token comment\">\/* \u5bf9\u5e94\u5177\u4f53\u5b9e\u73b0&#xff08;\u5982 ae_epoll_state&#xff09; *\/<\/span><br \/>\n    aeBeforeSleepProc <span class=\"token operator\">*<\/span>beforesleep<span class=\"token punctuation\">;<\/span><br \/>\n    aeBeforeSleepProc <span class=\"token operator\">*<\/span>aftersleep<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> flags<span class=\"token punctuation\">;<\/span>               <span class=\"token comment\">\/* \u72b6\u6001\u4f4d *\/<\/span><br \/>\n    <span class=\"token keyword\">void<\/span> <span class=\"token operator\">*<\/span>privdata<span class=\"token punctuation\">[<\/span><span class=\"token number\">2<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span>       <span class=\"token comment\">\/* 8.4 \u5f15\u5165&#xff1a;\u5b58\u50a8\u4e0a\u4e0b\u6587&#xff0c;privdata[0] \u5e38\u6307\u5411 server \u5b9e\u4f8b *\/<\/span><br \/>\n<span class=\"token punctuation\">}<\/span> aeEventLoop<span class=\"token punctuation\">;<\/span><\/p>\n<p>privdata[2] \u7684\u8bbe\u8ba1\u610f\u56fe\u662f\u51cf\u5c11\u5bf9\u5168\u5c40\u53d8\u91cf server \u7684\u76f4\u63a5\u5f15\u7528\u3002\u5728 initServer \u6d41\u7a0b\u4e2d&#xff0c;server \u7684\u5730\u5740\u4f1a\u88ab\u5b58\u5165 privdata[0]&#xff0c;\u4f7f\u5f97\u4e8b\u4ef6\u5e93\u5728\u56de\u8c03\u65f6\u80fd\u66f4\u4f18\u96c5\u5730\u83b7\u53d6\u4e0a\u4e0b\u6587\u3002<\/p>\n<h4>1.3.2 \u5ba2\u6237\u7aef\u62bd\u8c61 client<\/h4>\n<p>\u6bcf\u4e00\u4e2a\u7f51\u7edc\u8fde\u63a5\u5728 Redis \u5185\u90e8\u90fd\u5bf9\u5e94\u4e00\u4e2a client \u7ed3\u6784\u4f53&#xff0c;\u5176\u5173\u952e\u7684 I\/O \u5b57\u6bb5\u5982\u4e0b&#xff1a;<\/p>\n<p><span class=\"token comment\">\/* \u6e90\u7801\u4f4d\u7f6e: src\/server.h *\/<\/span><br \/>\n<span class=\"token keyword\">typedef<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">client<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    connection <span class=\"token operator\">*<\/span>conn<span class=\"token punctuation\">;<\/span>         <span class=\"token comment\">\/* \u6307\u5411\u5e95\u5c42\u8fde\u63a5\u5bf9\u8c61\u7684\u6307\u9488 *\/<\/span><br \/>\n    sds querybuf<span class=\"token punctuation\">;<\/span>             <span class=\"token comment\">\/* \u8f93\u5165\u7f13\u51b2\u533a&#xff0c;\u4fdd\u5b58\u539f\u59cb\u8bf7\u6c42\u6570\u636e *\/<\/span><br \/>\n    <span class=\"token class-name\">size_t<\/span> querybuf_peak<span class=\"token punctuation\">;<\/span>     <span class=\"token comment\">\/* \u5cf0\u503c\u5185\u5b58\u5360\u7528\u8bb0\u5f55 *\/<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> argc<span class=\"token punctuation\">;<\/span>                 <span class=\"token comment\">\/* \u89e3\u6790\u51fa\u7684\u53c2\u6570\u4e2a\u6570 *\/<\/span><br \/>\n    robj <span class=\"token operator\">*<\/span><span class=\"token operator\">*<\/span>argv<span class=\"token punctuation\">;<\/span>              <span class=\"token comment\">\/* \u89e3\u6790\u51fa\u7684\u53c2\u6570\u6570\u7ec4 *\/<\/span><br \/>\n    <span class=\"token keyword\">char<\/span> buf<span class=\"token punctuation\">[<\/span>PROTO_REPLY_CHUNK_BYTES<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/* 16KB \u9759\u6001\u56de\u590d\u7f13\u51b2\u533a *\/<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> bufpos<span class=\"token punctuation\">;<\/span>               <span class=\"token comment\">\/* \u9759\u6001\u7f13\u51b2\u533a\u5f53\u524d\u5df2\u7528\u5b57\u8282\u6570 *\/<\/span><br \/>\n    list <span class=\"token operator\">*<\/span>reply<span class=\"token punctuation\">;<\/span>              <span class=\"token comment\">\/* \u52a8\u6001\u56de\u590d\u94fe\u8868&#xff0c;\u5904\u7406\u5927\u6570\u636e\u91cf\u54cd\u5e94 *\/<\/span><br \/>\n    <span class=\"token comment\">\/* &#8230; \u72b6\u6001\u4f4d\u53ca\u5176\u4ed6\u5b57\u6bb5 *\/<\/span><br \/>\n<span class=\"token punctuation\">}<\/span> client<span class=\"token punctuation\">;<\/span><\/p>\n<h4>1.3.3 \u521d\u59cb\u5316\u6d41\u7a0b&#xff1a;\u4ece main \u5230 aeMain<\/h4>\n<p>Redis 8.4 \u7684\u7f51\u7edc\u521d\u59cb\u5316\u662f\u4e00\u4e2a\u4ece\u5185\u6838 Socket \u7ed1\u5b9a\u5230\u7528\u6237\u6001\u4e8b\u4ef6\u9a71\u52a8\u6846\u67b6\u6302\u8f7d\u7684\u8fc7\u7a0b\u3002<\/p>\n<h5>1.3.3.1 \u4e8b\u4ef6\u5f15\u64ce\u7684\u521d\u59cb\u5316&#xff1a;aeCreateEventLoop<\/h5>\n<p>\u5728 server.c \u7684 initServer \u51fd\u6570\u4e2d&#xff0c;\u7b2c\u4e00\u6b65\u5c31\u662f\u521b\u5efa aeEventLoop\u3002<\/p>\n<p><span class=\"token comment\">\/* \u6e90\u7801\u4f4d\u7f6e: server.c -&gt; initServer *\/<\/span><br \/>\nserver<span class=\"token punctuation\">.<\/span>el <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">aeCreateEventLoop<\/span><span class=\"token punctuation\">(<\/span>server<span class=\"token punctuation\">.<\/span>maxclients <span class=\"token operator\">&#043;<\/span> CONFIG_FDSET_INCR<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>server<span class=\"token punctuation\">.<\/span>el <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token constant\">NULL<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token function\">serverLog<\/span><span class=\"token punctuation\">(<\/span>LL_WARNING<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Failed creating the event loop. Out of memory?&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token function\">exit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/* 8.4 \u5173\u952e\u70b9&#xff1a;\u5c06 server \u5b9e\u4f8b\u6307\u9488\u5b58\u5165 privdata[0] *\/<\/span><br \/>\nserver<span class=\"token punctuation\">.<\/span>el<span class=\"token operator\">-&gt;<\/span>privdata<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>server<span class=\"token punctuation\">;<\/span> <\/p>\n<p>aeCreateEventLoop \u5185\u90e8\u4f1a\u8c03\u7528 aeApiCreate\u3002\u5728 Linux \u73af\u5883\u4e0b&#xff0c;\u8fd9\u5bf9\u5e94 ae_epoll.c&#xff0c;\u5b83\u4f1a\u6267\u884c epoll_create \u5e76\u521d\u59cb\u5316 aeApiState\u3002\u6b64\u65f6&#xff0c;Redis \u5df2\u7ecf\u7533\u8bf7\u597d\u4e86\u5b58\u653e\u5c31\u7eea\u4e8b\u4ef6\u7684\u5185\u5b58\u7a7a\u95f4&#xff08;fired \u6570\u7ec4&#xff09;\u3002<\/p>\n<h5>1.3.3.2 \u7ed1\u5b9a\u76d1\u542c\u4e0e anet \u62bd\u8c61\u5c42<\/h5>\n<p>Redis \u9700\u8981\u5728\u6307\u5b9a\u7684\u7aef\u53e3\u8fdb\u884c\u76d1\u542c\u3002\u8fd9\u4e2a\u903b\u8f91\u5728 listenToPort \u4e2d\u5b8c\u6210&#xff0c;\u5b83\u901a\u8fc7 anet.c \u5c01\u88c5\u7684\u7cfb\u7edf\u8c03\u7528\u6765\u521b\u5efa\u975e\u963b\u585e\u7684 Socket\u3002<\/p>\n<ul>\n<li>\u6d41\u7a0b&#xff1a;listenToPort -&gt; anetTcpServer -&gt; _anetTcpServer -&gt; anetListen\u3002<\/li>\n<li>\u6e90\u7801\u7ec6\u8282&#xff1a;\n<ul>\n<li>socket()&#xff1a;\u521b\u5efa\u5957\u63a5\u5b57\u3002<\/li>\n<li>anetSetReuseAddr()&#xff1a;\u8bbe\u7f6e SO_REUSEADDR&#xff0c;\u9632\u6b62\u670d\u52a1\u91cd\u542f\u65f6\u7aef\u53e3\u88ab\u5360\u7528\u3002<\/li>\n<li>anetNonBlock()&#xff1a;\u5173\u952e\u6b65\u9aa4&#xff0c;\u5c06 FD \u8bbe\u4e3a\u975e\u963b\u585e\u6a21\u5f0f\u3002Redis \u7684\u6240\u6709\u7f51\u7edc IO \u5fc5\u987b\u662f\u975e\u963b\u585e\u7684\u3002<\/li>\n<li>bind() &amp; listen()&#xff1a;\u7ed1\u5b9a\u7aef\u53e3\u5e76\u5f00\u542f\u76d1\u542c&#xff0c;\u8bbe\u7f6e backlog&#xff08;\u7531 server.tcp_backlog \u914d\u7f6e&#xff09;\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h5>1.3.3.3 \u6ce8\u518c Accept \u56de\u8c03&#xff1a;\u5efa\u7acb\u8fde\u63a5\u7684\u5165\u53e3<\/h5>\n<p>\u6709\u4e86\u76d1\u542c FD&#xff08;\u6587\u4ef6\u63cf\u8ff0\u7b26&#xff09;\u540e&#xff0c;Redis \u5fc5\u987b\u544a\u8bc9\u4e8b\u4ef6\u5faa\u73af&#xff1a;\u201c\u5982\u679c\u6709\u65b0\u8fde\u63a5\u8fdb\u6765&#xff0c;\u8bf7\u53eb\u6211\u3002\u201d<\/p>\n<p>\u5728 8.4 \u4e2d&#xff0c;\u8fd9\u4e2a\u8fc7\u7a0b\u901a\u8fc7 connection \u5c42\u7684 connSetReadHandler \u5b8c\u6210&#xff0c;\u800c\u4e0d\u518d\u662f\u76f4\u63a5\u64cd\u4f5c aeCreateFileEvent\u3002<\/p>\n<p><span class=\"token comment\">\/* \u6e90\u7801\u4f4d\u7f6e: server.c -&gt; initServer *\/<\/span><br \/>\n<span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span>j <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span> j <span class=\"token operator\">&lt;<\/span> server<span class=\"token punctuation\">.<\/span>ipfd_count<span class=\"token punctuation\">;<\/span> j<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/* \u5c01\u88c5\u76d1\u542c FD \u4e3a connection \u5bf9\u8c61&#xff0c;\u5e76\u6ce8\u518c acceptTcpHandler *\/<\/span><br \/>\n    <span class=\"token function\">connSetReadHandler<\/span><span class=\"token punctuation\">(<\/span>server<span class=\"token punctuation\">.<\/span>ipfd_conn<span class=\"token punctuation\">[<\/span>j<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span> acceptTcpHandler<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<ul>\n<li>acceptTcpHandler&#xff1a;\u8fd9\u662f\u5904\u7406 TCP \u8fde\u63a5\u5efa\u7acb\u7684\u5165\u53e3\u51fd\u6570\u3002<\/li>\n<li>\u6ce8\u518c\u903b\u8f91&#xff1a;connSetReadHandler \u5185\u90e8\u6700\u7ec8\u4f1a\u8c03\u7528 aeCreateFileEvent&#xff0c;\u5c06 server.ipfd \u6ce8\u518c\u5230 epoll \u5b9e\u4f8b\u4e2d&#xff0c;\u5173\u6ce8 AE_READABLE \u4e8b\u4ef6\u3002<\/li>\n<\/ul>\n<h5>1.3.3.4 \u5f00\u542f\u5faa\u73af&#xff1a;aeMain \u4e0e\u4e8b\u4ef6\u5904\u7406\u903b\u8f91<\/h5>\n<p>\u4e00\u5207\u5c31\u7eea\u540e&#xff0c;main \u51fd\u6570\u6700\u540e\u4e00\u884c\u8c03\u7528 aeMain(server.el)&#xff0c;Redis \u6b63\u5f0f\u8fdb\u5165\u963b\u585e\u7b49\u5f85\u72b6\u6001\u3002<\/p>\n<p><span class=\"token comment\">\/* \u6e90\u7801\u4f4d\u7f6e: ae.c *\/<\/span><br \/>\n<span class=\"token keyword\">void<\/span> <span class=\"token function\">aeMain<\/span><span class=\"token punctuation\">(<\/span>aeEventLoop <span class=\"token operator\">*<\/span>eventLoop<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    eventLoop<span class=\"token operator\">-&gt;<\/span>stop <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">while<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>eventLoop<span class=\"token operator\">-&gt;<\/span>stop<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/* \u8fdb\u5165\u4e8b\u4ef6\u5904\u7406\u4e3b\u903b\u8f91 *\/<\/span><br \/>\n        <span class=\"token function\">aeProcessEvents<\/span><span class=\"token punctuation\">(<\/span>eventLoop<span class=\"token punctuation\">,<\/span> AE_ALL_EVENTS<span class=\"token operator\">|<\/span><br \/>\n                                   AE_CALL_BEFORE_SLEEP<span class=\"token operator\">|<\/span><br \/>\n                                   AE_CALL_AFTER_SLEEP<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>aeProcessEvents \u7684\u6838\u5fc3\u65f6\u5e8f&#xff1a;<\/p>\n<li>BeforeSleep&#xff1a;\u5728\u8fdb\u5165 epoll_wait \u963b\u585e\u4e4b\u524d&#xff0c;\u5904\u7406\u4e00\u4e9b\u201c\u987a\u5e26\u201d\u7684\u4efb\u52a1\u3002\u4f8b\u5982&#xff1a;\u5904\u7406\u5df2\u7ecf\u89e3\u6790\u5b8c\u547d\u4ee4\u7684 Client \u8bfb\u5199\u961f\u5217&#xff08;Threaded IO \u76f8\u5173&#xff09;\u3001\u540c\u6b65 AOF \u5230\u78c1\u76d8\u3001\u63a8\u9001\u96c6\u7fa4\u72b6\u6001\u7b49\u3002<\/li>\n<li>aeApiPoll&#xff1a;\u8c03\u7528 epoll_wait&#xff08;\u6216 io_uring \u7b49&#xff09;&#xff0c;\u4e3b\u7ebf\u7a0b\u5728\u6b64\u5904\u963b\u585e\u3002<\/li>\n<li>AfterSleep&#xff1a;\u4ece epoll_wait \u5524\u9192\u540e\u7acb\u5373\u6267\u884c\u7684\u4efb\u52a1\u3002<\/li>\n<li>\u5904\u7406\u5c31\u7eea\u4e8b\u4ef6&#xff1a;\u904d\u5386 fired \u6570\u7ec4&#xff0c;\u6839\u636e\u4e8b\u4ef6\u7c7b\u578b&#xff08;READ\/WRITE&#xff09;\u6267\u884c\u76f8\u5e94\u7684\u56de\u8c03\u51fd\u6570&#xff08;\u5982 readQueryFromClient \u6216 sendReplyToClient&#xff09;\u3002<\/li>\n<h5>1.3.3.5 8.4 \u7279\u6027&#xff1a;\u4e8b\u4ef6\u5faa\u73af\u7684 Flag \u63a7\u5236<\/h5>\n<p>\u5728 8.4 \u7684 aeProcessEvents \u4e2d&#xff0c;\u53ef\u4ee5\u901a\u8fc7 eventLoop-&gt;flags \u7cbe\u7ec6\u5316\u63a7\u5236\u4e8b\u4ef6\u5904\u7406\u884c\u4e3a\u3002\u4f8b\u5982 AE_DONT_WAIT \u6807\u5fd7\u4f4d\u53ef\u4ee5\u8ba9\u5faa\u73af\u7acb\u5373\u8fd4\u56de\u800c\u4e0d\u963b\u585e&#xff0c;\u8fd9\u5728 Redis \u5185\u90e8\u7684\u4e00\u4e9b\u975e\u963b\u585e\u6d4b\u8bd5\u811a\u672c\u548c\u7279\u5b9a\u7684\u5b50\u8fdb\u7a0b\u540c\u6b65\u903b\u8f91\u4e2d\u975e\u5e38\u6709\u7528\u3002<\/p>\n<h3>1.4 Redis 8.4 \u62bd\u8c61\u8fde\u63a5\u5c42&#xff08;Connection Layer&#xff09;<\/h3>\n<p>\u4e3a\u4e86\u652f\u6301\u591a\u79cd\u4f20\u8f93\u534f\u8bae&#xff08;TCP\u3001TLS&#xff09;&#xff0c;Redis 8.4 \u4f7f\u7528\u4e86\u201c\u865a\u51fd\u6570\u8868\u201d\u7684\u8bbe\u8ba1\u601d\u60f3\u3002\u6240\u6709\u7684 I\/O \u64cd\u4f5c\u90fd\u4e0d\u518d\u76f4\u63a5\u8c03\u7528\u7cfb\u7edf read\/write&#xff0c;\u800c\u662f\u901a\u8fc7 connection \u5bf9\u8c61\u3002<\/p>\n<p><span class=\"token comment\">\/* \u6e90\u7801\u4f4d\u7f6e: src\/connection.h *\/<\/span><br \/>\n<span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">ConnectionType<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">void<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">*<\/span>accept<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">(<\/span>connection <span class=\"token operator\">*<\/span>conn<span class=\"token punctuation\">,<\/span> ConnectionCallbackFunc accept_handler<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">*<\/span>write<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">(<\/span>connection <span class=\"token operator\">*<\/span>conn<span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">const<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token operator\">*<\/span>buf<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">size_t<\/span> len<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">*<\/span>read<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">(<\/span>connection <span class=\"token operator\">*<\/span>conn<span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token operator\">*<\/span>buf<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">size_t<\/span> len<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">void<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">*<\/span>close<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">(<\/span>connection <span class=\"token operator\">*<\/span>conn<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token comment\">\/* &#8230; *\/<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>\u5728 connection.c \u4e2d&#xff0c;\u9ed8\u8ba4\u7684 CT_Socket \u5b9e\u73b0\u4e86\u539f\u751f\u7684 TCP \u64cd\u4f5c\u3002\u5f53\u4e00\u4e2a\u8fde\u63a5\u5efa\u7acb\u65f6&#xff0c;\u5176 conn-&gt;type \u4f1a\u6307\u5411\u5bf9\u5e94\u7684 ConnectionType\u3002\u8fd9\u79cd\u8bbe\u8ba1\u4f7f\u5f97 Redis \u5728\u5904\u7406 TLS \u65f6&#xff0c;\u4e0a\u5c42 networking.c \u7684\u903b\u8f91\u4fdd\u6301\u4e0d\u53d8\u3002<\/p>\n<h3>1.5 \u603b\u7ed3&#xff1a;\u7f51\u7edc\u6a21\u578b\u7684\u672c\u8d28<\/h3>\n<p>Redis 8.4 \u7f51\u7edc\u6a21\u578b\u7684\u672c\u8d28\u662f&#xff1a;\u5229\u7528 aeEventLoop \u5c06\u963b\u585e\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\u62bd\u8c61\u4e3a\u4e8b\u4ef6&#xff0c;\u901a\u8fc7 connection \u5c4f\u853d\u4f20\u8f93\u5c42\u5dee\u5f02&#xff0c;\u6700\u540e\u5728\u4e3b\u7ebf\u7a0b\u7684\u4e8b\u4ef6\u5faa\u73af\u4e2d\u901a\u8fc7\u56de\u8c03\u51fd\u6570&#xff08;Callback&#xff09;\u5b8c\u6210\u4ece\u201c\u8fde\u63a5\u63a5\u6536\u201d\u5230\u201c\u534f\u8bae\u89e3\u6790\u201d\u518d\u5230\u201c\u547d\u4ee4\u6267\u884c\u201d\u7684\u5168\u8fc7\u7a0b\u3002<\/p>\n<p>\u5c3d\u7ba1\u6709 Threaded I\/O&#xff0c;\u4f46\u5176\u6838\u5fc3\u903b\u8f91\u4f9d\u7136\u4e25\u683c\u9075\u5b88 Reactor \u6a21\u5f0f&#xff0c;\u591a\u7ebf\u7a0b\u4ec5\u4f5c\u4e3a\u8bfb\u5199\u7f13\u51b2\u533a\u7684\u52a0\u901f\u5668\u3002<\/p>\n<p>\u4e3a\u4e86\u8ba9\u4f60\u7684\u535a\u6587\u7b2c\u4e00\u90e8\u5206\u66f4\u5177\u89c6\u89c9\u51b2\u51fb\u529b\u5e76\u6e05\u6670\u5c55\u73b0 Redis 8.4 \u7684\u542f\u52a8\u903b\u8f91&#xff0c;\u6211\u4e3a\u4f60\u8bbe\u8ba1\u4e86\u4e00\u4e2a Mermaid \u56fe\u3002\u8fd9\u4e2a\u56fe\u7ed3\u5408\u4e86\u51fd\u6570\u8c03\u7528\u94fe\u8def\u4e0e\u6838\u5fc3\u6570\u636e\u7ed3\u6784\u7684\u6620\u5c04\u5173\u7cfb\u3002<\/p>\n<p>  #mermaid-svg-0yOY2GoFfHCYNNGa{font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0yOY2GoFfHCYNNGa .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0yOY2GoFfHCYNNGa .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0yOY2GoFfHCYNNGa .error-icon{fill:#552222;}#mermaid-svg-0yOY2GoFfHCYNNGa .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0yOY2GoFfHCYNNGa .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0yOY2GoFfHCYNNGa .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0yOY2GoFfHCYNNGa .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0yOY2GoFfHCYNNGa .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0yOY2GoFfHCYNNGa .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0yOY2GoFfHCYNNGa .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0yOY2GoFfHCYNNGa .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0yOY2GoFfHCYNNGa .marker.cross{stroke:#333333;}#mermaid-svg-0yOY2GoFfHCYNNGa svg{font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0yOY2GoFfHCYNNGa p{margin:0;}#mermaid-svg-0yOY2GoFfHCYNNGa .label{font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;color:#333;}#mermaid-svg-0yOY2GoFfHCYNNGa .cluster-label text{fill:#333;}#mermaid-svg-0yOY2GoFfHCYNNGa .cluster-label span{color:#333;}#mermaid-svg-0yOY2GoFfHCYNNGa .cluster-label span p{background-color:transparent;}#mermaid-svg-0yOY2GoFfHCYNNGa .label text,#mermaid-svg-0yOY2GoFfHCYNNGa span{fill:#333;color:#333;}#mermaid-svg-0yOY2GoFfHCYNNGa .node rect,#mermaid-svg-0yOY2GoFfHCYNNGa .node circle,#mermaid-svg-0yOY2GoFfHCYNNGa .node ellipse,#mermaid-svg-0yOY2GoFfHCYNNGa .node polygon,#mermaid-svg-0yOY2GoFfHCYNNGa .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0yOY2GoFfHCYNNGa .rough-node .label text,#mermaid-svg-0yOY2GoFfHCYNNGa .node .label text,#mermaid-svg-0yOY2GoFfHCYNNGa .image-shape .label,#mermaid-svg-0yOY2GoFfHCYNNGa .icon-shape .label{text-anchor:middle;}#mermaid-svg-0yOY2GoFfHCYNNGa .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0yOY2GoFfHCYNNGa .rough-node .label,#mermaid-svg-0yOY2GoFfHCYNNGa .node .label,#mermaid-svg-0yOY2GoFfHCYNNGa .image-shape .label,#mermaid-svg-0yOY2GoFfHCYNNGa .icon-shape .label{text-align:center;}#mermaid-svg-0yOY2GoFfHCYNNGa .node.clickable{cursor:pointer;}#mermaid-svg-0yOY2GoFfHCYNNGa .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0yOY2GoFfHCYNNGa .arrowheadPath{fill:#333333;}#mermaid-svg-0yOY2GoFfHCYNNGa .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0yOY2GoFfHCYNNGa .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0yOY2GoFfHCYNNGa .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0yOY2GoFfHCYNNGa .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0yOY2GoFfHCYNNGa .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0yOY2GoFfHCYNNGa .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0yOY2GoFfHCYNNGa .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0yOY2GoFfHCYNNGa .cluster text{fill:#333;}#mermaid-svg-0yOY2GoFfHCYNNGa .cluster span{color:#333;}#mermaid-svg-0yOY2GoFfHCYNNGa div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0yOY2GoFfHCYNNGa .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0yOY2GoFfHCYNNGa rect.text{fill:none;stroke-width:0;}#mermaid-svg-0yOY2GoFfHCYNNGa .icon-shape,#mermaid-svg-0yOY2GoFfHCYNNGa .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0yOY2GoFfHCYNNGa .icon-shape p,#mermaid-svg-0yOY2GoFfHCYNNGa .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0yOY2GoFfHCYNNGa .icon-shape rect,#mermaid-svg-0yOY2GoFfHCYNNGa .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0yOY2GoFfHCYNNGa .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0yOY2GoFfHCYNNGa .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0yOY2GoFfHCYNNGa :root{&#8211;mermaid-font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;}#mermaid-svg-0yOY2GoFfHCYNNGa .mainNode&gt;*{fill:#2d3436!important;stroke:#dfe6e9!important;stroke-width:2px!important;color:#fff!important;font-weight:bold!important;}#mermaid-svg-0yOY2GoFfHCYNNGa .mainNode span{fill:#2d3436!important;stroke:#dfe6e9!important;stroke-width:2px!important;color:#fff!important;font-weight:bold!important;}#mermaid-svg-0yOY2GoFfHCYNNGa .mainNode tspan{fill:#fff!important;}#mermaid-svg-0yOY2GoFfHCYNNGa .logicNode&gt;*{fill:#0984e3!important;stroke:#74b9ff!important;stroke-width:1px!important;color:#fff!important;}#mermaid-svg-0yOY2GoFfHCYNNGa .logicNode span{fill:#0984e3!important;stroke:#74b9ff!important;stroke-width:1px!important;color:#fff!important;}#mermaid-svg-0yOY2GoFfHCYNNGa .logicNode tspan{fill:#fff!important;}#mermaid-svg-0yOY2GoFfHCYNNGa .structNode&gt;*{fill:#6c5ce7!important;stroke:#a29bfe!important;stroke-width:1px!important;color:#fff!important;}#mermaid-svg-0yOY2GoFfHCYNNGa .structNode span{fill:#6c5ce7!important;stroke:#a29bfe!important;stroke-width:1px!important;color:#fff!important;}#mermaid-svg-0yOY2GoFfHCYNNGa .structNode tspan{fill:#fff!important;}#mermaid-svg-0yOY2GoFfHCYNNGa .storageNode&gt;*{fill:#00b894!important;stroke:#55efc4!important;stroke-width:1px!important;color:#fff!important;}#mermaid-svg-0yOY2GoFfHCYNNGa .storageNode span{fill:#00b894!important;stroke:#55efc4!important;stroke-width:1px!important;color:#fff!important;}#mermaid-svg-0yOY2GoFfHCYNNGa .storageNode tspan{fill:#fff!important;}#mermaid-svg-0yOY2GoFfHCYNNGa .highlightNode&gt;*{fill:#d63031!important;stroke:#ff7675!important;stroke-width:2px!important;color:#fff!important;}#mermaid-svg-0yOY2GoFfHCYNNGa .highlightNode span{fill:#d63031!important;stroke:#ff7675!important;stroke-width:2px!important;color:#fff!important;}#mermaid-svg-0yOY2GoFfHCYNNGa .highlightNode tspan{fill:#fff!important;} <\/p>\n<p>         <span class=\"nodeLabel\">5. \u4e8b\u4ef6\u5faa\u73af\u6d41\u8f6c &#8211; aeMain<\/span> <\/p>\n<p>         <span class=\"nodeLabel\">4. \u4e1a\u52a1\u5904\u7406\u5c42 &#8211; networking.c<\/span> <\/p>\n<p>         <span class=\"nodeLabel\">3. \u8fde\u63a5\u62bd\u8c61\u5c42 &#8211; connection.c<\/span> <\/p>\n<p>         <span class=\"nodeLabel\">2. \u4e8b\u4ef6\u9a71\u52a8\u5185\u6838 &#8211; ae.c<\/span> <\/p>\n<p>         <span class=\"nodeLabel\">1. \u542f\u52a8\u521d\u59cb\u5316 &#8211; server.c<\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/p>\n<p>\u653e\u5165\u4efb\u52a1<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/p>\n<p>\u9501\u5b9a\u6267\u884c<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/p>\n<p>\u56de\u8c03\u8c03\u7528<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/p>\n<p>\u89e6\u53d1\u89e3\u6790<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span style=\"color:#fff !important;font-weight:bold !important\" class=\"nodeLabel\"><\/p>\n<p>main()<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#fff !important;font-weight:bold !important\" class=\"nodeLabel\"><\/p>\n<p>initServer()<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#fff !important\" class=\"nodeLabel\"><\/p>\n<p>listenToPort() (anet.c)<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#fff !important\" class=\"nodeLabel\"><\/p>\n<p>connSetReadHandler(\u7ed1\u5b9a\u76d1\u542c\u4e8b\u4ef6)<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#fff !important;font-weight:bold !important\" class=\"nodeLabel\"><\/p>\n<p><b>aeEventLoop<\/b>(\u4e8b\u4ef6\u5faa\u73af\u6838\u5fc3)<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#fff !important\" class=\"nodeLabel\"><\/p>\n<p><b>privdata[2]<\/b>(0:server\u6307\u9488 \/ 1:ctx)<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#fff !important\" class=\"nodeLabel\"><\/p>\n<p>ae_epoll.c \/ ae_io_uring.c<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#fff !important\" class=\"nodeLabel\"><\/p>\n<p><b>ConnectionType<\/b>(TCP\/TLS\/Unix \u865a\u51fd\u6570\u8868)<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#fff !important\" class=\"nodeLabel\"><\/p>\n<p>connection \u5b9e\u4f8b(fd, read\/write_handler)<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#fff !important\" class=\"nodeLabel\"><\/p>\n<p><b>client \u7ed3\u6784\u4f53<\/b>(\u72b6\u6001\u673a\/\u547d\u4ee4\u6267\u884c)<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#fff !important\" class=\"nodeLabel\"><\/p>\n<p><b>Pending Queues<\/b>(read\/write \u5f85\u5904\u7406\u961f\u5217)<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#fff !important\" class=\"nodeLabel\"><\/p>\n<p>querybuf (SDS) \/ Reply List<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#fff !important\" class=\"nodeLabel\"><\/p>\n<p>beforeSleep()(\u5206\u53d1\u591a\u7ebf\u7a0bIO\u4efb\u52a1)<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#fff !important\" class=\"nodeLabel\"><\/p>\n<p>aeApiPoll()(epoll_wait)<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#fff !important\" class=\"nodeLabel\"><\/p>\n<p>\u4e8b\u4ef6\u56de\u8c03\u5904\u7406(\u904d\u5386 fired \u6570\u7ec4)<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#fff !important\" class=\"nodeLabel\"><\/p>\n<p>I\/O Threads(\u5e76\u884c\u89e3\u6790\/\u5e76\u884c\u5199\u7f13\u51b2)<\/p>\n<p><\/span> <\/p>\n<hr \/>\n<p>\u56fe\u8868\u8bf4\u660e&#xff08;\u53ef\u4f5c\u4e3a\u535a\u6587\u6ce8\u91ca&#xff09;&#xff1a;<\/p>\n<li>\u89e3\u8026\u8bbe\u8ba1 (PrivData)&#xff1a;\u56fe\u4e2d\u7279\u522b\u6807\u6ce8\u4e86 Redis 8.4 \u5f15\u5165\u7684 privdata[0] \u8d4b\u503c\u903b\u8f91\u3002\u8fd9\u5728\u6e90\u7801\u5206\u6790\u4e2d\u662f\u4e00\u4e2a\u5173\u952e\u70b9&#xff0c;\u5b83\u6807\u5fd7\u7740 ae \u4e8b\u4ef6\u5e93\u5f00\u59cb\u5c1d\u8bd5\u8131\u79bb\u5bf9 server \u5168\u5c40\u53d8\u91cf\u7684\u5f3a\u4f9d\u8d56\u3002<\/li>\n<li>\u62bd\u8c61\u5c42 (Connection Layer)&#xff1a;\u5728 listenToPort \u4e0e acceptTcpHandler \u4e4b\u95f4&#xff0c;Redis \u5e76\u4e0d\u662f\u76f4\u63a5\u64cd\u4f5c\u539f\u59cb FD&#xff0c;\u800c\u662f\u901a\u8fc7 connection \u7ed3\u6784\u4f53\u8fdb\u884c\u5c01\u88c5\u3002\u8fd9\u5c42\u201c\u865a\u51fd\u6570\u8868\u201d\u8bbe\u8ba1\u4f7f\u5f97 Redis 8.4 \u80fd\u5728\u4e0d\u6539\u52a8\u6838\u5fc3\u903b\u8f91\u7684\u60c5\u51b5\u4e0b\u652f\u6301 TLS \u6216\u4e0d\u540c\u7684\u5185\u6838\u540e\u7aef&#xff08;\u5982 io_uring&#xff09;\u3002<\/li>\n<li>\u6838\u5fc3\u5faa\u73af (EventLoop)&#xff1a;\n<ul>\n<li>beforeSleep&#xff1a;\u8fd9\u662f Redis \u7f51\u7edc\u6a21\u578b\u7684\u201c\u9ec4\u91d1\u5730\u5e26\u201d\u3002\u5f88\u591a\u975e\u5f02\u6b65\u7684 IO \u4f18\u5316&#xff08;\u5982 Threaded IO \u7684\u4efb\u52a1\u5206\u53d1&#xff09;\u90fd\u5728\u8fdb\u5165 epoll_wait \u4e4b\u524d\u5b8c\u6210\u3002<\/li>\n<li>aeApiPoll&#xff1a;\u6839\u636e\u7f16\u8bd1\u9009\u9879&#xff0c;\u8fd9\u91cc\u4f1a\u52a8\u6001\u6307\u5411 ae_epoll.c \u6216\u6700\u65b0\u7684 ae_io_uring.c\u3002<\/li>\n<li>Handlers&#xff1a;\u5f53\u4e00\u4e2a\u8bfb\u4e8b\u4ef6\u89e6\u53d1\u65f6&#xff0c;\u5b83\u4f1a\u6d41\u8f6c\u5230 client \u7ed3\u6784\u4f53&#xff0c;\u5f00\u59cb\u8fdb\u884c RESP \u534f\u8bae\u89e3\u6790\u3002<\/li>\n<\/ul>\n<\/li>\n<h2>\u7b2c\u4e8c\u90e8\u5206&#xff1a;\u4e8b\u4ef6\u9a71\u52a8\u5f15\u64ce ae \u7684\u5c01\u88c5\u4e0e\u5b9e\u73b0<\/h2>\n<p>Redis \u7684 ae&#xff08;Async Event&#xff09;\u5f15\u64ce\u662f\u4e00\u4e2a\u9ad8\u5ea6\u7cbe\u7b80\u7684 Reactor \u6846\u67b6\u3002\u5728 Redis 8.4 \u4e2d&#xff0c;\u5b83\u4f9d\u7136\u4fdd\u6301\u4e86\u4e0d\u5230 1000 \u884c C \u4ee3\u7801\u7684\u6781\u81f4\u7b80\u6d01&#xff0c;\u901a\u8fc7\u5bf9\u591a\u8def\u590d\u7528 API \u7684\u9759\u6001\u5c01\u88c5&#xff0c;\u5b9e\u73b0\u4e86\u9ad8\u6027\u80fd\u7684\u4e8b\u4ef6\u5faa\u73af\u3002<\/p>\n<h3>2.1 \u4e8b\u4ef6\u72b6\u6001\u7ba1\u7406&#xff1a;aeEventLoop \u4e0e\u6838\u5fc3\u7ed3\u6784<\/h3>\n<p>Redis \u4f9d\u7136\u575a\u6301\u4f7f\u7528\u7b80\u5355\u76f4\u63a5\u7684\u6570\u7ec4\u7d22\u5f15\u6765\u7ba1\u7406\u6587\u4ef6\u63cf\u8ff0\u7b26&#xff08;FD&#xff09;\u3002\u8fd9\u79cd O(1) \u7684\u67e5\u627e\u65b9\u5f0f\u89c4\u907f\u4e86\u54c8\u5e0c\u8868\u6216\u5e73\u8861\u6811\u5e26\u6765\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u6bdb\u523a\u3002<\/p>\n<h4>2.1.1 \u6838\u5fc3\u6570\u636e\u7ed3\u6784<\/h4>\n<p><span class=\"token comment\">\/* \u6e90\u7801\u4f4d\u7f6e: src\/ae.h (Redis 8.4) *\/<\/span><br \/>\n<span class=\"token keyword\">typedef<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">aeFileEvent<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> mask<span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/* AE_READABLE, AE_WRITABLE, AE_BARRIER *\/<\/span><br \/>\n    aeFileProc <span class=\"token operator\">*<\/span>rfileProc<span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/* \u8bfb\u56de\u8c03 *\/<\/span><br \/>\n    aeFileProc <span class=\"token operator\">*<\/span>wfileProc<span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/* \u5199\u56de\u8c03 *\/<\/span><br \/>\n    <span class=\"token keyword\">void<\/span> <span class=\"token operator\">*<\/span>clientData<span class=\"token punctuation\">;<\/span>      <span class=\"token comment\">\/* \u6307\u5411 connection \u6216 client \u5b9e\u4f8b *\/<\/span><br \/>\n<span class=\"token punctuation\">}<\/span> aeFileEvent<span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token keyword\">typedef<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">aeEventLoop<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> maxfd<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> setsize<span class=\"token punctuation\">;<\/span><br \/>\n    aeFileEvent <span class=\"token operator\">*<\/span>events<span class=\"token punctuation\">;<\/span>   <span class=\"token comment\">\/* \u6ce8\u518c\u4e8b\u4ef6\u6570\u7ec4&#xff0c;\u4e0b\u6807\u5373 FD *\/<\/span><br \/>\n    aeFiredEvent <span class=\"token operator\">*<\/span>fired<span class=\"token punctuation\">;<\/span>   <span class=\"token comment\">\/* \u5df2\u5c31\u7eea\u4e8b\u4ef6\u6570\u7ec4 *\/<\/span><br \/>\n    aeTimeEvent <span class=\"token operator\">*<\/span>timeEventHead<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">void<\/span> <span class=\"token operator\">*<\/span>apidata<span class=\"token punctuation\">;<\/span>         <span class=\"token comment\">\/* \u6307\u5411\u5177\u4f53\u540e\u7aef&#xff08;\u5982 aeApiState&#xff09; *\/<\/span><br \/>\n    aeBeforeSleepProc <span class=\"token operator\">*<\/span>beforesleep<span class=\"token punctuation\">;<\/span><br \/>\n    aeBeforeSleepProc <span class=\"token operator\">*<\/span>aftersleep<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">void<\/span> <span class=\"token operator\">*<\/span>privdata<span class=\"token punctuation\">;<\/span>        <span class=\"token comment\">\/* \u5168\u5c40\u4e0a\u4e0b\u6587\u6307\u9488&#xff0c;\u6307\u5411 RedisServer *\/<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> flags<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span> aeEventLoop<span class=\"token punctuation\">;<\/span><\/p>\n<h3>2.2 \u591a\u8def\u590d\u7528\u5c42\u7684\u9002\u914d&#xff1a;\u7edf\u4e00\u62bd\u8c61\u4e0e\u540e\u7aef\u9009\u62e9<\/h3>\n<p>Redis \u7684 ae \u5f15\u64ce\u4e4b\u6240\u4ee5\u4e0d\u4f9d\u8d56\u4efb\u4f55\u7b2c\u4e09\u65b9\u5e93&#xff0c;\u662f\u56e0\u4e3a\u5b83\u5728\u6e90\u7801\u7ea7\u522b\u5b9e\u73b0\u4e86\u4e00\u5957\u201c\u9759\u6001\u591a\u6001\u201d\u7684\u9002\u914d\u5c42\u3002<\/p>\n<h4>2.2.1 \u7f16\u8bd1\u671f\u540e\u7aef\u9009\u62e9\u673a\u5236<\/h4>\n<p>Redis \u5e76\u4e0d\u5728\u8fd0\u884c\u65f6\u5224\u65ad\u73af\u5883&#xff0c;\u800c\u662f\u5728\u7f16\u8bd1\u671f\u901a\u8fc7\u9884\u5904\u7406\u5668\u51b3\u5b9a\u5305\u542b\u54ea\u4e2a\u540e\u7aef\u3002\u5728 ae.c \u7684\u672b\u5c3e&#xff0c;\u4f18\u5148\u7ea7\u5982\u4e0b&#xff1a;<\/p>\n<p><span class=\"token comment\">\/* \u6e90\u7801\u4f4d\u7f6e: src\/ae.c *\/<\/span><br \/>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">ifdef<\/span> <span class=\"token expression\">HAVE_IO_URING<\/span><\/span><br \/>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">include<\/span> <span class=\"token string\">&#034;ae_io_uring.c&#034;<\/span>  <span class=\"token comment\">\/* Linux 5.1&#043; \u4e14\u5f00\u542f\u4e86 io_uring \u652f\u6301 *\/<\/span><\/span><br \/>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">else<\/span><\/span><br \/>\n    <span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">ifdef<\/span> <span class=\"token expression\">HAVE_EPOLL<\/span><\/span><br \/>\n    <span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">include<\/span> <span class=\"token string\">&#034;ae_epoll.c&#034;<\/span>     <span class=\"token comment\">\/* Linux \u9ed8\u8ba4 *\/<\/span><\/span><br \/>\n    <span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">else<\/span><\/span><br \/>\n        <span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">ifdef<\/span> <span class=\"token expression\">HAVE_KQUEUE<\/span><\/span><br \/>\n        <span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">include<\/span> <span class=\"token string\">&#034;ae_kqueue.c&#034;<\/span>    <span class=\"token comment\">\/* macOS\/FreeBSD *\/<\/span><\/span><br \/>\n        <span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">else<\/span><\/span><br \/>\n        <span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">include<\/span> <span class=\"token string\">&#034;ae_select.c&#034;<\/span>    <span class=\"token comment\">\/* \u4fdd\u5e95\u65b9\u6848 *\/<\/span><\/span><br \/>\n        <span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">endif<\/span><\/span><br \/>\n    <span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">endif<\/span><\/span><br \/>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">endif<\/span><\/span><\/p>\n<h4>2.2.2 \u7edf\u4e00 API \u63a5\u53e3\u5951\u7ea6&#xff1a;\u89e3\u8026\u7684\u8fb9\u754c<\/h4>\n<p>\u4e3a\u4e86\u5c4f\u853d\u5185\u6838\u5dee\u5f02&#xff0c;Redis \u5b9a\u4e49\u4e86\u4e00\u5957\u6807\u51c6\u7684 API \u7b7e\u540d\u3002\u8fd9\u5957\u5951\u7ea6\u89c4\u5b9a\u4e86\u65e0\u8bba\u5e95\u5c42\u662f epoll\u3001kqueue \u8fd8\u662f io_uring&#xff0c;\u90fd\u5fc5\u987b\u5411 ae.c \u63d0\u4f9b\u4e00\u7ec4\u529f\u80fd\u4e00\u81f4\u7684\u51fd\u6570\u3002<\/p>\n<p>\u4e3b\u8981\u63a5\u53e3\u5982\u4e0b&#xff1a;<\/p>\n<ul>\n<li>aeApiCreate: \u5206\u914d\u5e76\u521d\u59cb\u5316\u540e\u7aef\u79c1\u6709\u72b6\u6001&#xff08;apidata&#xff09;\u3002<\/li>\n<li>aeApiAddEvent \/ aeApiDelEvent: \u6ce8\u518c\u6216\u5220\u9664 FD \u5173\u6ce8\u7684\u4e8b\u4ef6\u3002<\/li>\n<li>aeApiPoll: \u6838\u5fc3\u963b\u585e\u51fd\u6570&#xff0c;\u8d1f\u8d23\u6536\u96c6\u5c31\u7eea\u4e8b\u4ef6\u5e76\u586b\u5145\u5230 eventLoop-&gt;fired\u3002<\/li>\n<\/ul>\n<h4>2.2.3 \u63a9\u7801\u6620\u5c04&#xff1a;\u5951\u7ea6\u80cc\u540e\u7684\u201c\u8bed\u4e49\u7ffb\u8bd1\u201d<\/h4>\n<p>2.2.2 \u5b9a\u4e49\u4e86\u201c\u505a\u4ec0\u4e48\u201d&#xff0c;\u800c 2.2.3 \u89e3\u51b3\u4e86\u201c\u600e\u4e48\u8bf4\u201d\u7684\u95ee\u9898\u3002 \u8fd9\u662f\u63a5\u53e3\u5951\u7ea6\u80fd\u591f\u843d\u5730\u7684\u6838\u5fc3\u903b\u8f91\u3002<\/p>\n<p>\u7531\u4e8e\u4e0d\u540c\u5185\u6838\u5bf9\u201c\u53ef\u8bfb\u201d\u6216\u201c\u53ef\u5199\u201d\u7684\u63cf\u8ff0\u7b26\u5b8c\u5168\u4e0d\u540c&#xff08;\u4f8b\u5982 Linux \u7528\u4f4d\u63a9\u7801 EPOLLIN&#xff0c;\u800c BSD \u7528\u5e38\u91cf EVFILT_READ&#xff09;&#xff0c;\u6bcf\u4e2a\u540e\u7aef\u5b9e\u73b0\u5728\u6267\u884c 2.2.2 \u5b9a\u4e49\u7684\u63a5\u53e3\u65f6&#xff0c;\u7b2c\u4e00\u6b65\u5c31\u662f\u8fdb\u884c \u903b\u8f91\u63a9\u7801\u5230\u5185\u6838\u539f\u751f\u6807\u5fd7\u7684\u7ffb\u8bd1\u3002<\/p>\n<h5>2.2.3.1. \u6620\u5c04\u6d41\u7a0b\u5206\u6790<\/h5>\n<p>\u4ee5 aeApiAddEvent \u4e3a\u4f8b&#xff0c;\u5176\u5185\u90e8\u903b\u8f91\u5c55\u793a\u4e86\u4e24\u8005\u7684\u8026\u5408\u5173\u7cfb&#xff1a;<\/p>\n<p><span class=\"token comment\">\/* \u8fd9\u79cd\u201c\u5951\u7ea6 &#043; \u6620\u5c04\u201d\u7684\u6a21\u5f0f\u5b58\u5728\u4e8e\u6bcf\u4e2a ae_*.c \u4e2d *\/<\/span><br \/>\n<span class=\"token keyword\">static<\/span> <span class=\"token keyword\">int<\/span> <span class=\"token function\">aeApiAddEvent<\/span><span class=\"token punctuation\">(<\/span>aeEventLoop <span class=\"token operator\">*<\/span>eventLoop<span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">int<\/span> fd<span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">int<\/span> mask<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    aeApiState <span class=\"token operator\">*<\/span>state <span class=\"token operator\">&#061;<\/span> eventLoop<span class=\"token operator\">-&gt;<\/span>apidata<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ [2.2.3 \u7684\u6838\u5fc3&#xff1a;\u63a9\u7801\u7ffb\u8bd1]<\/span><br \/>\n    <span class=\"token comment\">\/\/ \u5c06 ae \u5c42\u7684 AE_READABLE\/AE_WRITABLE \u8f6c\u6362\u4e3a\u5185\u6838\u539f\u751f\u6807\u5fd7<\/span><br \/>\n    <span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">epoll_event<\/span> ee <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> op <span class=\"token operator\">&#061;<\/span> eventLoop<span class=\"token operator\">-&gt;<\/span>events<span class=\"token punctuation\">[<\/span>fd<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>mask <span class=\"token operator\">&#061;&#061;<\/span> AE_NONE <span class=\"token operator\">?<\/span><br \/>\n            EPOLL_CTL_ADD <span class=\"token operator\">:<\/span> EPOLL_CTL_MOD<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>mask <span class=\"token operator\">&amp;<\/span> AE_READABLE<span class=\"token punctuation\">)<\/span> ee<span class=\"token punctuation\">.<\/span>events <span class=\"token operator\">|&#061;<\/span> EPOLLIN<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>mask <span class=\"token operator\">&amp;<\/span> AE_WRITABLE<span class=\"token punctuation\">)<\/span> ee<span class=\"token punctuation\">.<\/span>events <span class=\"token operator\">|&#061;<\/span> EPOLLOUT<span class=\"token punctuation\">;<\/span><br \/>\n    ee<span class=\"token punctuation\">.<\/span>data<span class=\"token punctuation\">.<\/span>fd <span class=\"token operator\">&#061;<\/span> fd<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ [2.2.2 \u7684\u5b9e\u73b0&#xff1a;\u6267\u884c\u7cfb\u7edf\u8c03\u7528]<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token function\">epoll_ctl<\/span><span class=\"token punctuation\">(<\/span>state<span class=\"token operator\">-&gt;<\/span>epfd<span class=\"token punctuation\">,<\/span> op<span class=\"token punctuation\">,<\/span> fd<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>ee<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">return<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h5>2.2.3.2. \u5bf9\u6bd4&#xff1a;\u4e0d\u540c\u5e73\u53f0\u7684\u7ffb\u8bd1\u5dee\u5f02<\/h5>\n<p>\u901a\u8fc7\u8fd9\u79cd\u6620\u5c04\u673a\u5236&#xff0c;ae \u5f15\u64ce\u5728\u4fdd\u6301\u9876\u5c42\u903b\u8f91\u7b80\u6d01\u7684\u540c\u65f6&#xff0c;\u517c\u5bb9\u4e86\u5b8c\u5168\u4e0d\u540c\u7684\u901a\u77e5\u6a21\u578b&#xff1a;<\/p>\n<table>\n<tr>\u62bd\u8c61\u5c42 (AE Mask)Linux (epoll) \u6620\u5c04\u7ed3\u679cBSD (kqueue) \u6620\u5c04\u7ed3\u679cio_uring \u6620\u5c04\u7ed3\u679c<\/tr>\n<tbody>\n<tr>\n<td align=\"left\">AE_READABLE<\/td>\n<td align=\"left\">EPOLLIN<\/td>\n<td align=\"left\">EVFILT_READ<\/td>\n<td align=\"left\">POLLIN<\/td>\n<\/tr>\n<tr>\n<td align=\"left\">AE_WRITABLE<\/td>\n<td align=\"left\">EPOLLOUT<\/td>\n<td align=\"left\">EVFILT_WRITE<\/td>\n<td align=\"left\">POLLOUT<\/td>\n<\/tr>\n<tr>\n<td align=\"left\">\u6620\u5c04\u903b\u8f91<\/td>\n<td align=\"left\">\u4f4d\u8fd0\u7b97 (OR)<\/td>\n<td align=\"left\">\u7ed3\u6784\u4f53\u6570\u7ec4\u8f6c\u6362<\/td>\n<td align=\"left\">SQE \u5c5e\u6027\u8bbe\u7f6e<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>2.2.4 \u4e3a\u4ec0\u4e48\u8fd9\u79cd\u8bbe\u8ba1\u662f\u9ad8\u6548\u7684&#xff1f;<\/h4>\n<ul>\n<li>\u96f6\u62bd\u8c61\u5f00\u9500&#xff1a;\u7531\u4e8e\u6620\u5c04\u662f\u5728\u7f16\u8bd1\u671f\u901a\u8fc7 include \u786e\u5b9a\u7684&#xff0c;\u6ca1\u6709\u865a\u51fd\u6570\u8868&#xff08;vtable&#xff09;\u7684\u8fd0\u884c\u65f6\u5f00\u9500\u3002<\/li>\n<li>\u8bed\u4e49\u5bf9\u9f50&#xff1a;ae.c \u53ea\u9700\u8981\u5904\u7406 AE_READABLE \u8fd9\u79cd\u903b\u8f91\u72b6\u6001&#xff0c;\u800c\u65e0\u9700\u5173\u5fc3\u5e95\u5c42\u662f\u8fb9\u7f18\u89e6\u53d1&#xff08;Edge Triggered&#xff09;\u8fd8\u662f\u6c34\u5e73\u89e6\u53d1&#xff08;Level Triggered&#xff09;&#xff0c;\u6240\u6709\u7684\u9002\u914d\u7ec6\u8282\u90fd\u88ab\u5c01\u9501\u5728 ae_*.c \u7684\u6620\u5c04\u5c42\u5185\u3002<\/li>\n<li>\u9632\u5fa1 FD \u590d\u7528&#xff1a;\u5728 8.4 \u6e90\u7801\u7684 aeApiPoll \u6620\u5c04\u4e2d&#xff0c;Redis \u4f1a\u6839\u636e fired \u6570\u7ec4\u7684\u53cd\u9988\u52a8\u6001\u66f4\u65b0 eventLoop-&gt;events&#xff0c;\u8fd9\u79cd\u53cc\u5411\u6620\u5c04\u786e\u4fdd\u4e86\u5728\u9ad8\u5e76\u53d1 FD \u9891\u7e41\u5173\u95ed\u548c\u91cd\u7528\u65f6&#xff0c;\u4e8b\u4ef6\u4e0d\u4f1a\u88ab\u8bef\u89e6\u53d1\u3002<\/li>\n<\/ul>\n<h3>2.3 \u8be6\u89e3 AE_BARRIER&#xff1a;\u8bfb\u5199\u987a\u5e8f\u7684\u201c\u53cd\u8f6c\u5c4f\u969c\u201d<\/h3>\n<p>\u8fd9\u662f Redis \u7f51\u7edc\u6a21\u578b\u4e2d\u6700\u6838\u5fc3\u7684\u4f18\u5316\u903b\u8f91\u3002\u5728\u6807\u51c6 Reactor \u4e2d&#xff0c;\u82e5 FD \u540c\u65f6\u53ef\u8bfb\u5199&#xff0c;\u901a\u5e38\u662f\u201c\u5148\u8bfb\u540e\u5199\u201d\u3002\u4f46\u4e3a\u4e86\u4f18\u5316\u54cd\u5e94\u5ef6\u8fdf&#xff0c;Redis 8.4 \u5f3a\u5316\u4e86 AE_BARRIER \u903b\u8f91\u3002<\/p>\n<h4>2.3.1 \u6838\u5fc3\u903b\u8f91&#xff1a;invert \u5206\u652f\u63a7\u5236<\/h4>\n<p>\u5728 aeProcessEvents \u5faa\u73af\u4e2d&#xff0c;\u901a\u8fc7\u68c0\u67e5 AE_BARRIER \u6539\u53d8\u56de\u8c03\u987a\u5e8f&#xff1a;<\/p>\n<p><span class=\"token keyword\">int<\/span> invert <span class=\"token operator\">&#061;<\/span> fe<span class=\"token operator\">-&gt;<\/span>mask <span class=\"token operator\">&amp;<\/span> AE_BARRIER<span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token comment\">\/* 1. \u60c5\u51b5 A&#xff1a;\u6b63\u5e38\u987a\u5e8f (No Barrier) \u2014\u2014 \u5148\u8bfb *\/<\/span><br \/>\n<span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>invert <span class=\"token operator\">&amp;&amp;<\/span> <span class=\"token punctuation\">(<\/span>mask <span class=\"token operator\">&amp;<\/span> AE_READABLE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    fe<span class=\"token operator\">-&gt;<\/span><span class=\"token function\">rfileProc<\/span><span class=\"token punctuation\">(<\/span>eventLoop<span class=\"token punctuation\">,<\/span>fd<span class=\"token punctuation\">,<\/span>fe<span class=\"token operator\">-&gt;<\/span>clientData<span class=\"token punctuation\">,<\/span>mask<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    fired<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    fe <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>eventLoop<span class=\"token operator\">-&gt;<\/span>events<span class=\"token punctuation\">[<\/span>fd<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/* \u5237\u65b0\u6307\u9488&#xff0c;\u9632\u6b62\u8bfb\u56de\u8c03\u5185\u5173\u95ed\u4e86 FD *\/<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/* 2. \u5199\u56de\u8c03\u6267\u884c *\/<\/span><br \/>\n<span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>mask <span class=\"token operator\">&amp;<\/span> AE_WRITABLE<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>fired <span class=\"token operator\">||<\/span> fe<span class=\"token operator\">-&gt;<\/span>wfileProc <span class=\"token operator\">!&#061;<\/span> fe<span class=\"token operator\">-&gt;<\/span>rfileProc<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        fe<span class=\"token operator\">-&gt;<\/span><span class=\"token function\">wfileProc<\/span><span class=\"token punctuation\">(<\/span>eventLoop<span class=\"token punctuation\">,<\/span>fd<span class=\"token punctuation\">,<\/span>fe<span class=\"token operator\">-&gt;<\/span>clientData<span class=\"token punctuation\">,<\/span>mask<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        fired<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/* 3. \u60c5\u51b5 B&#xff1a;\u5c4f\u969c\u53cd\u8f6c (With Barrier) \u2014\u2014 \u8bfb\u5728\u5199\u4e4b\u540e *\/<\/span><br \/>\n<span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>invert <span class=\"token operator\">&amp;&amp;<\/span> <span class=\"token punctuation\">(<\/span>mask <span class=\"token operator\">&amp;<\/span> AE_READABLE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>fired <span class=\"token operator\">||<\/span> fe<span class=\"token operator\">-&gt;<\/span>wfileProc <span class=\"token operator\">!&#061;<\/span> fe<span class=\"token operator\">-&gt;<\/span>rfileProc<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        fe<span class=\"token operator\">-&gt;<\/span><span class=\"token function\">rfileProc<\/span><span class=\"token punctuation\">(<\/span>eventLoop<span class=\"token punctuation\">,<\/span>fd<span class=\"token punctuation\">,<\/span>fe<span class=\"token operator\">-&gt;<\/span>clientData<span class=\"token punctuation\">,<\/span>mask<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        fired<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>2.3.2 \u4e3a\u4ec0\u4e48\u9700\u8981\u53cd\u8f6c&#xff1f;<\/h4>\n<ul>\n<li>\u964d\u4f4e Pipeline \u5ef6\u8fdf&#xff1a;\u5f53\u4e00\u4e2a\u8fde\u63a5\u65e2\u6709\u5f85\u53d1\u9001\u6570\u636e\u53c8\u6709\u5f85\u8bfb\u53d6\u8bf7\u6c42\u65f6&#xff0c;\u5148\u6267\u884c\u5199\u64cd\u4f5c\u53ef\u4ee5\u5c06\u4e0a\u4e2a\u8bf7\u6c42\u7684\u56de\u590d\u7acb\u5373\u53d1\u56de&#xff0c;\u907f\u514d\u5176\u5728\u5185\u5b58\u4e2d\u591a\u5f85\u4e00\u4e2a\u5faa\u73af\u5468\u671f\u3002<\/li>\n<li>\u786e\u4fdd\u540c\u6b65&#xff1a;\u5728 beforesleep \u9636\u6bb5\u5904\u7406\u56de\u590d\u5237\u65b0\u65f6&#xff0c;\u5982\u679c\u56e0\u4e3a\u5185\u6838\u7f13\u51b2\u533a\u6ee1\u800c\u6ce8\u518c\u4e86\u5199\u4e8b\u4ef6&#xff0c;\u8bbe\u7f6e Barrier \u53ef\u4ee5\u786e\u4fdd\u4e0b\u6b21\u5faa\u73af\u201c\u5148\u6e05\u7a7a\u65e7\u56de\u590d&#xff0c;\u518d\u8bfb\u5165\u65b0\u8bf7\u6c42\u201d&#xff0c;\u4fdd\u8bc1\u4e86\u5904\u7406\u903b\u8f91\u7684\u4e25\u683c\u7ebf\u6027\u3002<\/li>\n<\/ul>\n<h3>2.4 \u6838\u5fc3\u5904\u7406\u51fd\u6570 aeProcessEvents \u7684\u6df1\u5ea6\u6267\u884c\u6d41<\/h3>\n<p>\u8fd9\u662f Redis \u7684\u201c\u5fc3\u810f\u201d\u3002\u5728 8.4 \u4e2d&#xff0c;\u5b83\u4e25\u5bc6\u63a7\u5236\u7740\u4e3b\u7ebf\u7a0b\u3001IO \u7ebf\u7a0b\u4e0e\u5185\u6838\u7684\u901a\u4fe1\u8282\u594f\u3002<\/p>\n<h4>2.4.1 aeProcessEvents \u6838\u5fc3\u6e90\u7801\u89e3\u8bfb<\/h4>\n<p><span class=\"token comment\">\/* \u6e90\u7801\u4f4d\u7f6e: src\/ae.c (\u7ecf\u8fc7\u7cbe\u7b80\u4ee5\u7a81\u51fa\u6838\u5fc3\u6d41) *\/<\/span><br \/>\n<span class=\"token keyword\">int<\/span> <span class=\"token function\">aeProcessEvents<\/span><span class=\"token punctuation\">(<\/span>aeEventLoop <span class=\"token operator\">*<\/span>eventLoop<span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">int<\/span> flags<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> processed <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">,<\/span> numevents<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/* 1. \u8ba1\u7b97\u963b\u585e\u65f6\u95f4&#xff1a;\u5982\u679c\u8bbe\u7f6e\u4e86\u5b9a\u65f6\u5668&#xff0c;\u5219\u8ba1\u7b97\u6700\u8fd1\u4e00\u4e2a\u5b9a\u65f6\u5668\u8fd8\u5269\u591a\u4e45\u89e6\u53d1 *\/<\/span><br \/>\n    <span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">timespec<\/span> tv<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">*<\/span>tvp <span class=\"token operator\">&#061;<\/span> <span class=\"token constant\">NULL<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span><span class=\"token punctuation\">(<\/span>flags <span class=\"token operator\">&amp;<\/span> AE_DONT_WAIT<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        tvp <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">aeCalculatePollWait<\/span><span class=\"token punctuation\">(<\/span>eventLoop<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>tv<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/* 2. BeforeSleep&#xff1a;\u8fdb\u5165\u7cfb\u7edf\u8c03\u7528\u524d\u7684\u6700\u540e\u673a\u4f1a *\/<\/span><br \/>\n    <span class=\"token comment\">\/* \u8fd9\u91cc\u5904\u7406&#xff1a;Threaded-IO \u4efb\u52a1\u5206\u53d1\u3001\u6e05\u9664\u65e0\u6548\u8fde\u63a5\u3001AOF \u5ef6\u65f6\u5199\u5165\u7b49 *\/<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>eventLoop<span class=\"token operator\">-&gt;<\/span>beforesleep <span class=\"token operator\">!&#061;<\/span> <span class=\"token constant\">NULL<\/span> <span class=\"token operator\">&amp;&amp;<\/span> <span class=\"token punctuation\">(<\/span>flags <span class=\"token operator\">&amp;<\/span> AE_CALL_BEFORE_SLEEP<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        eventLoop<span class=\"token operator\">-&gt;<\/span><span class=\"token function\">beforesleep<\/span><span class=\"token punctuation\">(<\/span>eventLoop<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/* 3. \u6838\u5fc3\u963b\u585e\u70b9&#xff1a;\u8c03\u7528\u5c01\u88c5\u597d\u7684\u591a\u8def\u590d\u7528 API (epoll\/io_uring) *\/<\/span><br \/>\n    numevents <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">aeApiPoll<\/span><span class=\"token punctuation\">(<\/span>eventLoop<span class=\"token punctuation\">,<\/span> tvp<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/* 4. AfterSleep&#xff1a;\u4ece\u5185\u6838\u6001\u5524\u9192\u540e\u7684\u5373\u65f6\u94a9\u5b50 *\/<\/span><br \/>\n    <span class=\"token comment\">\/* \u8fd9\u91cc\u5904\u7406&#xff1a;\u7531\u6a21\u5757&#xff08;Modules&#xff09;\u89e6\u53d1\u7684\u963b\u585e\u89e3\u9664\u3001\u76d1\u63a7\u7edf\u8ba1\u7b49 *\/<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>eventLoop<span class=\"token operator\">-&gt;<\/span>aftersleep <span class=\"token operator\">!&#061;<\/span> <span class=\"token constant\">NULL<\/span> <span class=\"token operator\">&amp;&amp;<\/span> <span class=\"token punctuation\">(<\/span>flags <span class=\"token operator\">&amp;<\/span> AE_CALL_AFTER_SLEEP<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        eventLoop<span class=\"token operator\">-&gt;<\/span><span class=\"token function\">aftersleep<\/span><span class=\"token punctuation\">(<\/span>eventLoop<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/* 5. \u904d\u5386\u5df2\u5c31\u7eea\u7684\u4e8b\u4ef6\u6570\u7ec4 fired[] *\/<\/span><br \/>\n    <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token keyword\">int<\/span> j <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span> j <span class=\"token operator\">&lt;<\/span> numevents<span class=\"token punctuation\">;<\/span> j<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">int<\/span> fd <span class=\"token operator\">&#061;<\/span> eventLoop<span class=\"token operator\">-&gt;<\/span>fired<span class=\"token punctuation\">[<\/span>j<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>fd<span class=\"token punctuation\">;<\/span><br \/>\n        aeFileEvent <span class=\"token operator\">*<\/span>fe <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>eventLoop<span class=\"token operator\">-&gt;<\/span>events<span class=\"token punctuation\">[<\/span>fd<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">int<\/span> mask <span class=\"token operator\">&#061;<\/span> eventLoop<span class=\"token operator\">-&gt;<\/span>fired<span class=\"token punctuation\">[<\/span>j<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>mask<span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">int<\/span> fired <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/* &#8212; \u6838\u5fc3\u903b\u8f91&#xff1a;AE_BARRIER \u987a\u5e8f\u63a7\u5236 &#8212; *\/<\/span><br \/>\n        <span class=\"token keyword\">int<\/span> invert <span class=\"token operator\">&#061;<\/span> fe<span class=\"token operator\">-&gt;<\/span>mask <span class=\"token operator\">&amp;<\/span> AE_BARRIER<span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/* \u60c5\u51b5 A: \u9700\u8981\u53cd\u8f6c (Barrier\u7f6e\u4f4d) -&gt; \u5148\u5199\u540e\u8bfb *\/<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>invert <span class=\"token operator\">&amp;&amp;<\/span> <span class=\"token punctuation\">(<\/span>mask <span class=\"token operator\">&amp;<\/span> AE_READABLE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>fired <span class=\"token operator\">||<\/span> fe<span class=\"token operator\">-&gt;<\/span>wfileProc <span class=\"token operator\">!&#061;<\/span> fe<span class=\"token operator\">-&gt;<\/span>rfileProc<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                fe<span class=\"token operator\">-&gt;<\/span><span class=\"token function\">wfileProc<\/span><span class=\"token punctuation\">(<\/span>eventLoop<span class=\"token punctuation\">,<\/span>fd<span class=\"token punctuation\">,<\/span>fe<span class=\"token operator\">-&gt;<\/span>clientData<span class=\"token punctuation\">,<\/span>mask<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                fired<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                fe <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>eventLoop<span class=\"token operator\">-&gt;<\/span>events<span class=\"token punctuation\">[<\/span>fd<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u5237\u65b0\u6307\u9488&#xff0c;\u9632\u6b62\u56de\u8c03\u5185\u5173\u95ed\u4e86fd<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/* \u666e\u901a\u60c5\u51b5&#xff1a;\u8bfb\u64cd\u4f5c\u59cb\u7ec8\u4f18\u5148\u5904\u7406 *\/<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>invert <span class=\"token operator\">&amp;&amp;<\/span> <span class=\"token punctuation\">(<\/span>mask <span class=\"token operator\">&amp;<\/span> AE_READABLE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            fe<span class=\"token operator\">-&gt;<\/span><span class=\"token function\">rfileProc<\/span><span class=\"token punctuation\">(<\/span>eventLoop<span class=\"token punctuation\">,<\/span>fd<span class=\"token punctuation\">,<\/span>fe<span class=\"token operator\">-&gt;<\/span>clientData<span class=\"token punctuation\">,<\/span>mask<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            fired<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            fe <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>eventLoop<span class=\"token operator\">-&gt;<\/span>events<span class=\"token punctuation\">[<\/span>fd<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/* \u5199\u64cd\u4f5c\u5904\u7406 *\/<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>mask <span class=\"token operator\">&amp;<\/span> AE_WRITABLE<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>fired <span class=\"token operator\">||<\/span> fe<span class=\"token operator\">-&gt;<\/span>wfileProc <span class=\"token operator\">!&#061;<\/span> fe<span class=\"token operator\">-&gt;<\/span>rfileProc<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                fe<span class=\"token operator\">-&gt;<\/span><span class=\"token function\">wfileProc<\/span><span class=\"token punctuation\">(<\/span>eventLoop<span class=\"token punctuation\">,<\/span>fd<span class=\"token punctuation\">,<\/span>fe<span class=\"token operator\">-&gt;<\/span>clientData<span class=\"token punctuation\">,<\/span>mask<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                fired<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/* \u60c5\u51b5 B: \u9700\u8981\u53cd\u8f6c (Barrier\u7f6e\u4f4d) -&gt; \u6b64\u65f6\u624d\u6267\u884c\u8bfb *\/<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>invert <span class=\"token operator\">&amp;&amp;<\/span> <span class=\"token punctuation\">(<\/span>mask <span class=\"token operator\">&amp;<\/span> AE_READABLE<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&amp;&amp;<\/span> <span class=\"token operator\">!<\/span>fired<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            fe<span class=\"token operator\">-&gt;<\/span><span class=\"token function\">rfileProc<\/span><span class=\"token punctuation\">(<\/span>eventLoop<span class=\"token punctuation\">,<\/span>fd<span class=\"token punctuation\">,<\/span>fe<span class=\"token operator\">-&gt;<\/span>clientData<span class=\"token punctuation\">,<\/span>mask<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            fired<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n        processed<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/* 6. \u5904\u7406\u65f6\u95f4\u4e8b\u4ef6&#xff1a;\u6267\u884c serverCron \u7b49\u5b9a\u65f6\u4efb\u52a1 *\/<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>flags <span class=\"token operator\">&amp;<\/span> AE_TIME_EVENTS<span class=\"token punctuation\">)<\/span><br \/>\n        processed <span class=\"token operator\">&#043;&#061;<\/span> <span class=\"token function\">processTimeEvents<\/span><span class=\"token punctuation\">(<\/span>eventLoop<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">return<\/span> processed<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>2.4.2 \u6df1\u5ea6\u6267\u884c\u6d41\u5206\u6790<\/h4>\n<li>\n<p>\u65f6\u95f4\u7684\u7cbe\u786e\u8c03\u5ea6 (aeCalculatePollWait)&#xff1a; Redis \u5e76\u975e\u76f2\u76ee\u963b\u585e\u3002\u5b83\u4f1a\u68c0\u67e5\u65f6\u95f4\u4e8b\u4ef6\u94fe\u8868&#xff0c;\u8ba1\u7b97\u51fa\u8ddd\u79bb\u6700\u8fd1\u4e00\u4e2a\u4efb\u52a1&#xff08;\u5982 serverCron&#xff09;\u8fd8\u9700\u8981\u591a\u5c11\u6beb\u79d2&#xff0c;\u5e76\u5c06\u8be5\u503c\u4f5c\u4e3a aeApiPoll \u7684\u8d85\u65f6\u65f6\u95f4\u3002\u8fd9\u786e\u4fdd\u4e86 Redis \u65e2\u80fd\u9ad8\u6548\u5904\u7406 IO&#xff0c;\u53c8\u4e0d\u4f1a\u9519\u8fc7\u5b9a\u65f6\u4efb\u52a1\u3002<\/p>\n<\/li>\n<li>\n<p>beforesleep \u7684\u6218\u7565\u610f\u4e49&#xff1a; \u8fd9\u662f Redis \u6027\u80fd\u4f18\u5316\u7684\u6838\u5fc3\u3002\u5728 8.4 \u4e2d&#xff0c;Threaded-IO \u7684\u8bfb\u5199\u4efb\u52a1\u662f\u5728\u8fd9\u91cc\u6d3e\u53d1\u7ed9 IO \u7ebf\u7a0b\u7684\u3002\u8fd9\u610f\u5473\u7740\u5728\u4e3b\u7ebf\u7a0b\u8fdb\u5165 aeApiPoll \u963b\u585e\u7b49\u5f85\u65b0\u4e8b\u4ef6\u65f6&#xff0c;IO \u7ebf\u7a0b\u6b63\u5728\u5e76\u53d1\u5730\u5904\u7406\u65e7\u8bf7\u6c42\u7684\u7f16\u7801\u6216\u65b0\u8bf7\u6c42\u7684\u89e3\u6790\u3002<\/p>\n<\/li>\n<li>\n<p>AE_BARRIER \u7684\u4ee3\u7801\u4f53\u73b0&#xff1a; \u89c2\u5bdf\u6e90\u7801\u4e2d\u7684 invert \u903b\u8f91\u3002\u5728\u6807\u51c6 Reactor \u4e2d&#xff0c;\u8bfb\u4e8b\u4ef6\u603b\u662f\u5148\u4e8e\u5199\u4e8b\u4ef6\u3002\u4f46 Redis \u901a\u8fc7 invert \u6807\u5fd7&#xff0c;\u5141\u8bb8\u5728\u540c\u4e00\u4e2a\u5faa\u73af\u5185\u5148\u6267\u884c\u5199\u56de\u8c03&#xff08;\u56de\u590d\u5ba2\u6237\u7aef&#xff09;\u518d\u6267\u884c\u8bfb\u56de\u8c03&#xff08;\u8bfb\u53d6\u65b0\u8bf7\u6c42&#xff09;\u3002\u8fd9\u79cd\u7cbe\u7ec6\u63a7\u5236\u80fd\u663e\u8457\u538b\u4f4e\u5e73\u5747\u54cd\u5e94\u5ef6\u8fdf&#xff08;RTT&#xff09;\u3002<\/p>\n<\/li>\n<li>\n<p>\u9632\u5fa1\u6027\u7f16\u7a0b&#xff08;FD \u5237\u65b0&#xff09;&#xff1a; \u6ce8\u610f\u4ee3\u7801\u4e2d\u7684 fe &#061; &amp;eventLoop-&gt;events[fd]\u3002\u5728\u6267\u884c\u5b8c\u8bfb\u56de\u8c03\u540e&#xff0c;Redis \u4f1a\u91cd\u65b0\u83b7\u53d6\u4e00\u6b21 fe \u6307\u9488\u3002\u8fd9\u662f\u56e0\u4e3a\u8bfb\u56de\u8c03\u51fd\u6570\u53ef\u80fd\u4f1a\u56e0\u4e3a\u903b\u8f91\u5f02\u5e38&#xff08;\u5982\u5ba2\u6237\u7aef\u975e\u6cd5\u8bf7\u6c42&#xff09;\u76f4\u63a5\u5173\u95ed\u5e76\u91ca\u653e\u5f53\u524d\u8fde\u63a5\u3002\u5982\u679c\u4e0d\u5237\u65b0\u6307\u9488&#xff0c;\u540e\u7eed\u7684\u5199\u64cd\u4f5c\u5c06\u4f1a\u8bbf\u95ee\u91ce\u6307\u9488&#xff0c;\u5bfc\u81f4 Segmentation Fault\u3002<\/p>\n<\/li>\n<h3>2.5 Redis 8.4 \u5bf9 io_uring \u7684\u96c6\u6210\u5206\u6790&#xff1a;ae_io_uring.c<\/h3>\n<p>\u5728 Linux 5.1&#043; \u5185\u6838\u4e2d&#xff0c;io_uring \u7684\u51fa\u73b0\u6253\u7834\u4e86 epoll \u957f\u671f\u4ee5\u6765\u7684\u7edf\u6cbb\u5730\u4f4d\u3002Redis 8.4 \u901a\u8fc7 ae_io_uring.c \u5b9e\u73b0\u4e86\u5bf9\u8fd9\u4e00\u65b0\u7279\u6027\u7684\u53ef\u9009\u652f\u6301&#xff0c;\u5c06\u5176\u4f5c\u4e3a\u9ad8\u6027\u80fd\u73af\u5883\u4e0b\u7684\u9996\u9009\u540e\u7aef\u3002<\/p>\n<h4>2.5.1 \u4ec0\u4e48\u662f io_uring&#xff1f;\u2014\u2014 \u9769\u547d\u6027\u7684\u201c\u5171\u4eab\u5185\u5b58\u201d\u5f02\u6b65 IO<\/h4>\n<p>io_uring \u662f\u7531 Linux \u5185\u6838\u5927\u5e08 Jens Axboe&#xff08;\u4e5f\u662f fio \u7684\u4f5c\u8005&#xff09;\u5728 2019 \u5e74\u5f15\u5165\u7684\u4e00\u5957\u5168\u65b0\u7684\u5f02\u6b65 IO \u63a5\u53e3\u3002<\/p>\n<p>\u5728\u5b83\u51fa\u73b0\u4e4b\u524d&#xff0c;Linux \u4e3b\u8981\u4f9d\u9760 select\/poll\/epoll \u5904\u7406\u7f51\u7edc IO&#xff0c;\u4f9d\u9760 AIO \u5904\u7406\u78c1\u76d8 IO\u3002\u4f46\u8fd9\u4e9b\u65b9\u6848\u5728\u9ad8\u5e76\u53d1&#xff08;\u6bcf\u79d2\u767e\u4e07\u7ea7\u8bf7\u6c42&#xff09;\u4e0b\u90fd\u9762\u4e34\u7740\u540c\u6837\u7684\u963f\u5580\u7409\u65af\u4e4b\u8e35&#xff1a;<\/p>\n<li>\u9891\u7e41\u7684\u7cfb\u7edf\u8c03\u7528&#xff08;System Call&#xff09;\u5f00\u9500&#xff1a;\u6bcf\u6b21\u8c03\u7528 epoll_ctl \u6216 epoll_wait&#xff0c;CPU \u90fd\u8981\u4ece\u201c\u7528\u6237\u6001\u201d\u5207\u6362\u5230\u201c\u5185\u6838\u6001\u201d&#xff0c;\u8fd9\u79cd\u4e0a\u4e0b\u6587\u5207\u6362\u975e\u5e38\u6602\u8d35\u3002<\/li>\n<li>\u6570\u636e\u62f7\u8d1d&#xff1a;\u5185\u6838\u9700\u8981\u5c06\u4e8b\u4ef6\u4ece\u5185\u6838\u7a7a\u95f4\u62f7\u8d1d\u5230\u7528\u6237\u7a7a\u95f4\u7f13\u51b2\u533a\u3002<\/li>\n<p>io_uring \u7684\u6838\u5fc3\u7a81\u7834\u5728\u4e8e\u201c\u5185\u6838\u65c1\u8def\u201d\u8bbe\u8ba1&#xff1a;\u5b83\u5728\u7528\u6237\u6001\u548c\u5185\u6838\u6001\u4e4b\u95f4\u5efa\u7acb\u4e86\u4e24\u5757\u5171\u4eab\u5185\u5b58\u533a\u57df&#xff0c;\u5373\u4e24\u4e2a\u73af\u5f62\u7f13\u51b2\u533a&#xff08;Ring Buffer&#xff09;&#xff1a;<\/p>\n<ul>\n<li>SQ (Submission Queue)&#xff1a;\u63d0\u4ea4\u961f\u5217\u3002\u7528\u6237\u6001\u628a\u4efb\u52a1&#xff08;\u5982\u201c\u76d1\u542c FD\u201d&#xff09;\u653e\u8fdb\u53bb\u3002<\/li>\n<li>CQ (Completion Queue)&#xff1a;\u5b8c\u6210\u961f\u5217\u3002\u5185\u6838\u5b8c\u6210\u4efb\u52a1\u540e\u628a\u7ed3\u679c\u653e\u8fdb\u53bb\u3002<\/li>\n<\/ul>\n<p>\u5f62\u8c61\u6bd4\u55bb&#xff1a;<\/p>\n<ul>\n<li>epoll \u6a21\u5f0f&#xff1a;\u4f60\u6bcf\u6b21\u5bc4\u4fe1&#xff08;\u8bfb\u5199&#xff09;\u90fd\u8981\u4eb2\u81ea\u8dd1\u4e00\u8d9f\u90ae\u5c40&#xff0c;\u5728\u67dc\u53f0\u6392\u961f\u7b49\u529e\u4e8b\u5458\u5904\u7406\u3002<\/li>\n<li>io_uring \u6a21\u5f0f&#xff1a;\u4f60\u5728\u5bb6\u95e8\u53e3\u88c5\u4e86\u4e00\u4e2a\u53cc\u5411\u5feb\u9012\u67dc\u3002\u4f60\u60f3\u5bc4\u4fe1\u5c31\u653e\u8fdb\u201c\u63d0\u4ea4\u7bb1\u201d&#xff08;SQ&#xff09;&#xff0c;\u90ae\u5dee\u53d6\u8d70\u5904\u7406\u540e&#xff0c;\u628a\u56de\u4fe1\u653e\u8fdb\u201c\u6536\u4ef6\u7bb1\u201d&#xff08;CQ&#xff09;\u3002\u4f60\u53ea\u9700\u8981\u5b9a\u671f\u770b\u4e00\u773c\u5feb\u9012\u67dc&#xff0c;\u5168\u7a0b\u65e0\u9700\u8dd1\u90ae\u5c40&#xff08;\u51cf\u5c11\u7cfb\u7edf\u8c03\u7528&#xff09;\u3002<\/li>\n<\/ul>\n<h4>2.5.2 SQ \u4e0e CQ \u7684\u7ba1\u7406&#xff1a;Redis \u7684\u9002\u914d\u903b\u8f91<\/h4>\n<p>\u5728 ae_io_uring.c \u4e2d&#xff0c;Redis \u5c06\u8fd9\u5957\u673a\u5236\u65e0\u7f1d\u5d4c\u5165\u4e86 Reactor \u6a21\u578b&#xff1a;<\/p>\n<li>\u4efb\u52a1\u5206\u53d1 (SQ)&#xff1a;\u5f53 Redis \u8c03\u7528 aeApiAddEvent \u65f6&#xff0c;\u5b83\u4e0d\u518d\u7acb\u5373\u6267\u884c\u8017\u65f6\u7684\u7cfb\u7edf\u8c03\u7528&#xff0c;\u800c\u662f\u6784\u5efa\u4e00\u4e2a sqe&#xff08;\u63d0\u4ea4\u961f\u5217\u6761\u76ee&#xff09;\u653e\u5165 SQ \u4e2d\u3002\u5728 Redis 8.4 \u7684\u5355\u6b21\u4e8b\u4ef6\u5faa\u73af\u4e2d&#xff0c;\u591a\u4e2a\u4e8b\u4ef6\u53d8\u66f4\u53ef\u4ee5\u79ef\u538b\u5728\u4e00\u8d77&#xff0c;\u901a\u8fc7\u4e00\u6b21 io_uring_submit \u6279\u91cf\u4ea4\u7ed9\u5185\u6838\u3002<\/li>\n<li>\u5c31\u7eea\u83b7\u53d6 (CQ)&#xff1a;\u5728 aeApiPoll \u4e2d&#xff0c;Redis \u76f4\u63a5\u68c0\u67e5 CQ \u73af\u5f62\u7f13\u51b2\u533a\u3002\u5982\u679c\u5185\u6838\u5df2\u7ecf\u586b\u5145\u4e86\u5c31\u7eea\u4e8b\u4ef6&#xff0c;Redis \u901a\u8fc7\u7b80\u5355\u7684\u6307\u9488\u504f\u79fb\u5373\u53ef\u8bfb\u53d6\u7ed3\u679c\u3002\u8fd9\u4e00\u6b65\u5728\u7406\u60f3\u60c5\u51b5\u4e0b\u662f \u201c\u96f6\u7cfb\u7edf\u8c03\u7528\u201d \u7684\u3002<\/li>\n<h4>2.5.3 \u6838\u5fc3\u5b9e\u73b0\u7247\u6bb5<\/h4>\n<p><span class=\"token comment\">\/* ae_io_uring.c \u4e2d\u7684 poll \u5b9e\u73b0\u7b80\u8ff0 *\/<\/span><br \/>\n<span class=\"token keyword\">static<\/span> <span class=\"token keyword\">int<\/span> <span class=\"token function\">aeApiPoll<\/span><span class=\"token punctuation\">(<\/span>aeEventLoop <span class=\"token operator\">*<\/span>eventLoop<span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">timespec<\/span> <span class=\"token operator\">*<\/span>tvp<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    aeApiState <span class=\"token operator\">*<\/span>state <span class=\"token operator\">&#061;<\/span> eventLoop<span class=\"token operator\">-&gt;<\/span>apidata<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">io_uring_cqe<\/span> <span class=\"token operator\">*<\/span>cqe<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">unsigned<\/span> head<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/* 1. \u6279\u91cf\u63d0\u4ea4 SQ \u4e2d\u7684\u6240\u6709\u53d8\u66f4&#xff0c;\u5e76\u7b49\u5f85\u4e8b\u4ef6&#xff08;\u5982\u6709\u5fc5\u8981&#xff09; *\/<\/span><br \/>\n    <span class=\"token function\">io_uring_submit_and_wait<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>state<span class=\"token operator\">-&gt;<\/span>ring<span class=\"token punctuation\">,<\/span> wait_nr<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/* 2. \u76f4\u63a5\u904d\u5386 CQ \u73af\u5f62\u7f13\u51b2\u533a&#xff0c;\u83b7\u53d6\u5c31\u7eea IO \u4e8b\u4ef6 *\/<\/span><br \/>\n    <span class=\"token function\">io_uring_for_each_cqe<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>state<span class=\"token operator\">-&gt;<\/span>ring<span class=\"token punctuation\">,<\/span> head<span class=\"token punctuation\">,<\/span> cqe<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">ae_uring_user_data<\/span> <span class=\"token operator\">*<\/span>data <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">io_uring_cqe_get_data<\/span><span class=\"token punctuation\">(<\/span>cqe<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u5c06 cqe \u4e2d\u7684\u7ed3\u679c\u6620\u5c04\u56de eventLoop-&gt;fired \u6570\u7ec4<\/span><br \/>\n        <span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token comment\">\/\/ 3. \u66f4\u65b0\u5b8c\u6210\u961f\u5217\u5934\u6307\u9488&#xff0c;\u544a\u77e5\u5185\u6838\u5df2\u5904\u7406<\/span><br \/>\n    <span class=\"token function\">io_uring_cq_advance<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>state<span class=\"token operator\">-&gt;<\/span>ring<span class=\"token punctuation\">,<\/span> count<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>2.5.4 \u6027\u80fd\u6536\u76ca\u4e0e 8.4 \u7684\u6df1\u5ea6\u4f18\u5316<\/h4>\n<ul>\n<li>Batching&#xff08;\u6279\u91cf\u5316\u63d0\u4ea4&#xff09;&#xff1a;\u5728\u6781\u9ad8\u5e76\u53d1\u8fde\u63a5\u53d8\u52a8&#xff08;\u5982\u5927\u91cf\u77ed\u8fde\u63a5\u63a5\u5165&#xff09;\u65f6&#xff0c;io_uring \u76f8\u6bd4 epoll \u80fd\u663e\u8457\u51cf\u5c11 epoll_ctl \u4ea7\u751f\u7684 CPU \u6001\u5207\u6362\u5f00\u9500\u3002<\/li>\n<li>\u51cf\u5c11\u6570\u636e\u62f7\u8d1d&#xff1a;\u7531\u4e8e\u4f7f\u7528\u5171\u4eab\u5185\u5b58&#xff0c;\u5185\u6838\u4e0e Redis \u4e4b\u95f4\u4e0d\u9700\u8981\u53cd\u590d\u62f7\u8d1d\u4e8b\u4ef6\u63cf\u8ff0\u7b26\u7ed3\u6784\u4f53\u3002<\/li>\n<li>SQPOLL&#xff08;\u5185\u6838\u8f6e\u8be2&#xff09;\u652f\u6301&#xff1a;\u5982\u679c\u5f00\u542f\u4e86 IORING_SETUP_SQPOLL \u6807\u5fd7&#xff0c;\u5185\u6838\u4f1a\u542f\u52a8\u4e00\u4e2a\u4e13\u95e8\u7684\u5185\u6838\u7ebf\u7a0b\u6765\u626b\u63cf SQ \u961f\u5217\u3002\u8fd9\u610f\u5473\u7740 Redis \u751a\u81f3\u4e0d\u9700\u8981\u53d1\u8d77 enter \u7cfb\u7edf\u8c03\u7528\u6765\u89e6\u53d1\u63d0\u4ea4&#xff0c;\u5b9e\u73b0\u4e86\u771f\u6b63\u610f\u4e49\u4e0a\u7684 IO \u5c42\u5185\u6838\u9677\u5165\u96f6\u5f00\u9500\u3002<\/li>\n<\/ul>\n<h4>2.5.5 Redis \u7684\u96c6\u6210\u7b56\u7565&#xff1a;\u7a33\u5065\u7684\u201c\u6f14\u8fdb\u201d<\/h4>\n<p>\u5c3d\u7ba1 io_uring \u652f\u6301\u5b8c\u5168\u5f02\u6b65\u7684 read\/write&#xff0c;\u4f46\u5728 8.4 \u7248\u672c\u4e2d&#xff0c;Redis \u4f9d\u7136\u4e3b\u8981\u5229\u7528\u5176 POLL_ADD \u6a21\u5f0f\u6765\u66ff\u4ee3 epoll\u3002\u8fd9\u6837\u505a\u662f\u4e3a\u4e86\u5728\u7ef4\u6301\u5355\u7ebf\u7a0b Reactor \u72b6\u6001\u673a\u7b80\u5355\u6027\u7684\u540c\u65f6&#xff0c;\u6700\u5927\u9650\u5ea6\u69a8\u53d6 Linux \u65b0\u5185\u6838\u5e26\u6765\u7684\u8c03\u5ea6\u7ea2\u5229\u3002\u5bf9\u4e8e\u4e07\u5146\u7f51\u5361\u548c\u8d85\u9ad8 QPS \u573a\u666f&#xff0c;io_uring \u76f8\u6bd4 epoll \u901a\u5e38\u80fd\u5e26\u6765 10%~20% \u7684\u6027\u80fd\u63d0\u5347\u3002<\/p>\n<h3>2.6 \u7f51\u7edc\u4f18\u5316\u8981\u70b9\u603b\u7ed3<\/h3>\n<li>\u9632\u5fa1\u6027\u7f16\u7a0b&#xff1a;\u5728 8.4 \u6e90\u7801\u4e2d&#xff0c;\u6bcf\u6b21\u8bfb\u56de\u8c03\u6267\u884c\u540e\u5fc5\u5237\u65b0 fe \u6307\u9488&#xff0c;\u8fd9\u662f\u5e94\u5bf9\u590d\u6742\u591a\u7ebf\u7a0b\u73af\u5883\u4e0b FD \u52a8\u6001\u9500\u6bc1\u7684\u575a\u56fa\u9632\u7ebf\u3002<\/li>\n<li>\u8c03\u5ea6\u7cbe\u51c6\u6027&#xff1a;\u901a\u8fc7 AE_BARRIER \u4e0e beforesleep \u7684\u8054\u52a8&#xff0c;Redis \u8bc1\u660e\u4e86\u5373\u4f7f\u662f\u5355\u7ebf\u7a0b Reactor&#xff0c;\u4e5f\u80fd\u901a\u8fc7\u7cbe\u7ec6\u7684\u987a\u5e8f\u63a7\u5236\u69a8\u5e72\u786c\u4ef6\u6027\u80fd\u3002<\/li>\n<h2>\u7b2c\u4e09\u90e8\u5206&#xff1a;\u8fde\u63a5\u5c42\u7684\u62bd\u8c61\u8bbe\u8ba1&#xff08;Connection Layer&#xff09;<\/h2>\n<h3>3.1 \u6f14\u8fdb\u80cc\u666f&#xff1a;\u4ece\u201c\u539f\u59cb FD\u201d\u5230\u201c\u4f20\u8f93\u5c42\u65e0\u5173\u201d<\/h3>\n<p>\u5728 Redis 6.0 \u4e4b\u524d&#xff0c;Redis \u76f4\u63a5\u64cd\u4f5c\u6587\u4ef6\u63cf\u8ff0\u7b26&#xff08;FD&#xff09;&#xff0c;\u8bfb\u5199\u903b\u8f91\u76f4\u63a5\u8026\u5408 read() \u548c write() \u7cfb\u7edf\u8c03\u7528\u3002\u4f46\u968f\u7740 Redis 6.0 \u539f\u751f\u652f\u6301 TLS&#xff08;\u52a0\u5bc6\u4f20\u8f93&#xff09;\u4ee5\u53ca 8.4 \u5bf9\u590d\u6742\u7f51\u7edc\u73af\u5883\u7684\u9002\u914d&#xff0c;\u8fd9\u79cd\u201c\u786c\u7f16\u7801\u201d\u6a21\u5f0f\u96be\u4ee5\u4e3a\u7ee7\u3002<\/p>\n<h4>3.1.1 \u4e3a\u4ec0\u4e48\u9700\u8981 connection \u62bd\u8c61\u5c42&#xff1f;<\/h4>\n<li>\u5c4f\u853d TLS \u590d\u6742\u6027&#xff1a;\u666e\u901a TCP \u53ea\u9700 read()&#xff0c;\u4f46 TLS \u9700\u8981\u7ecf\u8fc7\u590d\u6742\u7684\u89e3\u5bc6\u548c\u72b6\u6001\u5904\u7406&#xff08;\u5982 SSL_read()&#xff09;\u3002<\/li>\n<li>\u5f02\u6b65\u63e1\u624b\u7ba1\u7406&#xff1a;TLS \u8fde\u63a5\u5728 TCP \u4e09\u6b21\u63e1\u624b\u540e&#xff0c;\u8fd8\u9700\u8981\u8fdb\u884c\u591a\u6b21\u5bc6\u94a5\u4ea4\u6362&#xff08;Handshake&#xff09;\u3002\u5728\u975e\u963b\u585e IO \u6a21\u5f0f\u4e0b&#xff0c;\u63e1\u624b\u8fc7\u7a0b\u662f\u788e\u7247\u5316\u7684&#xff0c;\u5fc5\u987b\u6709\u4e00\u4e2a\u72b6\u6001\u673a\u6765\u7ba1\u7406\u3002<\/li>\n<li>\u591a\u6001\u652f\u6301&#xff1a;\u901a\u8fc7\u865a\u51fd\u6570\u8868&#xff0c;\u8ba9\u4e1a\u52a1\u903b\u8f91&#xff08;networking.c&#xff09;\u65e0\u9700\u5173\u5fc3\u5e95\u5c42\u662f\u7eaf\u6587\u672c\u8fd8\u662f\u52a0\u5bc6\u6d41\u3002<\/li>\n<h3>3.2 \u6838\u5fc3\u7ed3\u6784&#xff1a;connection \u4e0e ConnectionType \u865a\u51fd\u6570\u8868<\/h3>\n<p>Redis 8.4 \u4f7f\u7528 C \u8bed\u8a00\u5b9e\u73b0\u4e86\u7c7b\u4f3c\u9762\u5411\u5bf9\u8c61\u7684\u591a\u6001\u6027\u3002<\/p>\n<h4>3.2.1 ConnectionType&#xff1a;\u63a5\u53e3\u5951\u7ea6<\/h4>\n<p>\u6bcf\u4e2a\u534f\u8bae&#xff08;TCP\u3001TLS\u3001Unix Socket&#xff09;\u90fd\u5b9e\u73b0\u4e86\u4e00\u5957\u51fd\u6570\u6307\u9488&#xff1a;<\/p>\n<p><span class=\"token comment\">\/* src\/connection.h *\/<\/span><br \/>\n<span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">ConnectionType<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/* \u5c4f\u853d\u5dee\u5f02\u7684\u5173\u952e&#xff1a;\u7edf\u4e00\u7684\u8bfb\u5199\u63a5\u53e3 *\/<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">*<\/span>read<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">(<\/span>connection <span class=\"token operator\">*<\/span>conn<span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token operator\">*<\/span>buf<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">size_t<\/span> len<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">*<\/span>write<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">(<\/span>connection <span class=\"token operator\">*<\/span>conn<span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">const<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token operator\">*<\/span>buf<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">size_t<\/span> len<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">*<\/span>accept<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">(<\/span>connection <span class=\"token operator\">*<\/span>conn<span class=\"token punctuation\">,<\/span> ConnectionCallbackFunc accept_handler<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token comment\">\/* \u63e1\u624b\u72b6\u6001\u8f6e\u8be2 *\/<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">*<\/span>handler<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">(<\/span>connection <span class=\"token operator\">*<\/span>conn<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<h4>3.2.2 connection&#xff1a;\u5e26\u72b6\u6001\u7684\u5bf9\u8c61<\/h4>\n<p>\u8fde\u63a5\u5bf9\u8c61\u4e0d\u518d\u53ea\u662f\u4e00\u4e2a\u6574\u6570 FD&#xff0c;\u5b83\u62e5\u6709\u751f\u547d\u5468\u671f\u548c\u72b6\u6001&#xff1a;<\/p>\n<p><span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">connection<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    ConnectionType <span class=\"token operator\">*<\/span>type<span class=\"token punctuation\">;<\/span>    <span class=\"token comment\">\/* \u6307\u5411 CT_TCP \u6216 CT_TLS *\/<\/span><br \/>\n    ConnectionState state<span class=\"token punctuation\">;<\/span>   <span class=\"token comment\">\/* CONN_STATE_ACCEPTING(\u63e1\u624b\u4e2d), CONNECTED, CLOSED *\/<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> fd<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">void<\/span> <span class=\"token operator\">*<\/span>private_data<span class=\"token punctuation\">;<\/span>      <span class=\"token comment\">\/* \u6307\u5411\u5173\u8054\u7684 client \u5b9e\u4f8b *\/<\/span><br \/>\n    <span class=\"token comment\">\/* \u56de\u8c03\u51fd\u6570 *\/<\/span><br \/>\n    ConnectionCallbackFunc conn_handler<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<h3>3.3 \u5f02\u6b65\u63e1\u624b\u72b6\u6001\u673a&#xff1a;\u4ee5 TLS \u4e3a\u4f8b<\/h3>\n<p>\u8fd9\u662f\u8fde\u63a5\u5c42\u6700\u7cbe\u5999\u7684\u8bbe\u8ba1&#xff1a;\u5728\u8fde\u63a5\u5b8c\u5168\u201c\u5c31\u7eea\u201d\u4e4b\u524d&#xff0c;\u4e1a\u52a1\u5c42 client \u662f\u4e0d\u53ef\u89c1\u7684\u3002<\/p>\n<h4>3.3.1 TLS \u63e1\u624b\u6d41\u8f6c\u8fc7\u7a0b<\/h4>\n<li>\u76d1\u542c\u89e6\u53d1&#xff1a;acceptTcpHandler \u63a5\u6536\u5230\u65b0\u8fde\u63a5&#xff0c;\u8c03\u7528 connCreateAccept()\u3002<\/li>\n<li>\u6302\u8d77\u4e1a\u52a1&#xff1a;\u5982\u679c\u662f TLS \u8fde\u63a5&#xff0c;\u72b6\u6001\u8bbe\u4e3a CONN_STATE_ACCEPTING\u3002\u6b64\u65f6 \u4e0d\u4f1a \u521b\u5efa client \u5bf9\u8c61\u3002<\/li>\n<li>\u6ce8\u518c\u63e1\u624b\u56de\u8c03&#xff1a;\u5e95\u5c42\u8c03\u7528 aeCreateFileEvent \u6ce8\u518c\u8bfb\u4e8b\u4ef6&#xff0c;\u4f46\u56de\u8c03\u6307\u5411 tlsHandshakeHandler\u3002<\/li>\n<li>\u5206\u7247\u6267\u884c&#xff1a;\n<ul>\n<li>ae \u89e6\u53d1\u8bfb\u4e8b\u4ef6 -&gt; \u8fdb\u5165\u63e1\u624b\u5904\u7406\u5668\u3002<\/li>\n<li>\u8c03\u7528 SSL_do_handshake()\u3002<\/li>\n<li>\u5982\u679c\u6570\u636e\u4e0d\u8db3&#xff08;WANT_READ&#xff09;&#xff0c;\u76f4\u63a5\u8fd4\u56de ae \u5faa\u73af&#xff0c;\u7b49\u5f85\u4e0b\u4e00\u6b21\u89e6\u53d1\u3002<\/li>\n<\/ul>\n<\/li>\n<li>\u6fc0\u6d3b\u4e1a\u52a1&#xff1a;\u76f4\u5230\u63e1\u624b\u6210\u529f&#xff0c;\u72b6\u6001\u8f6c\u4e3a CONNECTED&#xff0c;\u6b64\u65f6\u624d\u8c03\u7528 accept_handler&#xff08;\u5373 createClient&#xff09;&#xff0c;\u6b63\u5f0f\u8fdb\u5165 Redis \u547d\u4ee4\u5904\u7406\u6d41\u7a0b\u3002<\/li>\n<p>\u7ed3\u8bba&#xff1a;\u8fd9\u79cd\u8bbe\u8ba1\u786e\u4fdd\u4e86\u4e1a\u52a1\u903b\u8f91\u5c42\u6c38\u8fdc\u53ea\u80fd\u8bfb\u5230\u201c\u5df2\u7ecf\u89e3\u5bc6\u597d\u201d\u7684\u6e05\u6d01\u5b57\u8282\u6d41\u3002<\/p>\n<h3>3.4 \u5ba2\u6237\u7aef\u5bf9\u8c61 client \u7684\u521b\u5efa&#xff1a;createClient \u6e90\u7801\u8d70\u8bfb<\/h3>\n<p>\u4e00\u65e6\u8fde\u63a5\u5c42\u5224\u5b9a\u8fde\u63a5\u5c31\u7eea&#xff08;TCP \u5df2\u8fde\u6216 TLS \u5df2\u63e1\u624b&#xff09;&#xff0c;createClient \u624d\u4f1a\u88ab\u8c03\u7528&#xff0c;\u5c06 connection \u5c01\u88c5\u4e3a\u4e1a\u52a1\u5b9e\u4f53\u3002<\/p>\n<p><span class=\"token comment\">\/* src\/networking.c (Redis 8.4) *\/<\/span><br \/>\nclient <span class=\"token operator\">*<\/span><span class=\"token function\">createClient<\/span><span class=\"token punctuation\">(<\/span>connection <span class=\"token operator\">*<\/span>conn<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    client <span class=\"token operator\">*<\/span>c <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">zmalloc<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">sizeof<\/span><span class=\"token punctuation\">(<\/span>client<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>conn<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token function\">connNonBlock<\/span><span class=\"token punctuation\">(<\/span>conn<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>           <span class=\"token comment\">\/* \u786e\u4fdd\u975e\u963b\u585e *\/<\/span><br \/>\n        <span class=\"token function\">connEnableTcpNoDelay<\/span><span class=\"token punctuation\">(<\/span>conn<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>   <span class=\"token comment\">\/* \u7981\u7528 Nagle&#xff0c;\u4f18\u5316\u5ef6\u8fdf *\/<\/span><\/p>\n<p>        <span class=\"token comment\">\/* \u6838\u5fc3\u7ed1\u5b9a&#xff1a;\u5f53\u8fde\u63a5\u771f\u6b63\u6709\u4e1a\u52a1\u6570\u636e\u65f6&#xff0c;\u6267\u884c readQueryFromClient *\/<\/span><br \/>\n        <span class=\"token function\">connSetReadHandler<\/span><span class=\"token punctuation\">(<\/span>conn<span class=\"token punctuation\">,<\/span> readQueryFromClient<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token function\">connSetPrivateData<\/span><span class=\"token punctuation\">(<\/span>conn<span class=\"token punctuation\">,<\/span> c<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n    c<span class=\"token operator\">-&gt;<\/span>conn <span class=\"token operator\">&#061;<\/span> conn<span class=\"token punctuation\">;<\/span><br \/>\n    c<span class=\"token operator\">-&gt;<\/span>db <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>server<span class=\"token punctuation\">.<\/span>db<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>conn<span class=\"token punctuation\">)<\/span> <span class=\"token function\">linkClient<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/* \u52a0\u5165\u5168\u5c40\u5ba2\u6237\u7aef\u94fe\u8868 *\/<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> c<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h3>3.5 \u975e\u963b\u585e IO \u4e0e\u5185\u6838\u53c2\u6570\u63a7\u5236<\/h3>\n<p>\u4e3a\u4e86\u652f\u6491\u4e07\u5146\u7f51\u7edc\u4e0b\u7684\u6781\u81f4\u6027\u80fd&#xff0c;Redis \u5728\u8fde\u63a5\u5c42\u5bf9\u5185\u6838\u53c2\u6570\u8fdb\u884c\u4e86\u5fae\u64cd&#xff1a;<\/p>\n<li>O_NONBLOCK (\u975e\u963b\u585e\u6620\u5c04)&#xff1a; \u6240\u6709\u8fde\u63a5\u5728\u5efa\u7acb\u77ac\u95f4\u5373\u901a\u8fc7 anetNonBlock \u8bbe\u7f6e\u3002\u8fd9\u4fdd\u8bc1\u4e86 aeApiPoll \u5524\u9192\u540e&#xff0c;\u4efb\u4f55 read\/write \u90fd\u80fd\u7acb\u5373\u8fd4\u56de\u800c\u975e\u6302\u8d77\u4e3b\u7ebf\u7a0b\u3002<\/li>\n<li>TCP_NODELAY (\u5ef6\u8fdf\u514b\u661f)&#xff1a; Redis \u9ed8\u8ba4\u7981\u7528 Nagle \u7b97\u6cd5\u3002\u867d\u7136\u8fd9\u4f1a\u7565\u5fae\u964d\u4f4e\u5e26\u5bbd\u5229\u7528\u7387&#xff0c;\u4f46\u80fd\u5927\u5e45\u51cf\u5c11\u5c0f\u5305\u8bf7\u6c42\u7684\u5e73\u5747\u54cd\u5e94\u65f6\u95f4&#xff08;RTT&#xff09;&#xff0c;\u8fd9\u7b26\u5408 Redis \u5185\u5b58\u6570\u636e\u5e93\u7684\u5b9a\u4f4d\u3002<\/li>\n<li>SO_KEEPALIVE&#xff1a; \u7531 server.tcpkeepalive \u53c2\u6570\u63a7\u5236\u3002\u8fde\u63a5\u5c42\u901a\u8fc7\u5b9a\u65f6\u53d1\u9001\u63a2\u9488&#xff0c;\u6e05\u7406\u90a3\u4e9b\u56e0\u4e3a\u7f51\u7edc\u6ce2\u52a8\u3001\u9632\u706b\u5899\u8d85\u65f6\u800c\u5bfc\u81f4\u7684\u201c\u534a\u6253\u5f00\u8fde\u63a5&#xff08;Half-Open Connections&#xff09;\u201d&#xff0c;\u9632\u6b62 client \u5bf9\u8c61\u6cc4\u9732\u3002<\/li>\n<h3>3.6 \u603b\u7ed3<\/h3>\n<p>Redis 8.4 \u7684\u8fde\u63a5\u5c42\u5b9e\u73b0\u4e86 \u201c\u89e3\u8026\u201d\u4e0e\u201c\u6027\u80fd\u201d\u7684\u5e73\u8861&#xff1a;<\/p>\n<ul>\n<li>\u89e3\u8026&#xff1a;\u5e95\u5c42\u9a71\u52a8&#xff08;ae&#xff09;\u3001\u4f20\u8f93\u534f\u8bae&#xff08;connection&#xff09;\u3001\u4e1a\u52a1\u903b\u8f91&#xff08;client&#xff09;\u4e09\u8005\u4e92\u4e0d\u4f9d\u8d56\u3002<\/li>\n<li>\u6027\u80fd&#xff1a;\u901a\u8fc7\u5f02\u6b65\u63e1\u624b\u72b6\u6001\u673a&#xff0c;\u5373\u4f7f\u662f\u6602\u8d35\u7684 TLS \u63e1\u624b\u4e5f\u4e0d\u4f1a\u963b\u585e\u4e3b\u7ebf\u7a0b\u5904\u7406\u5176\u4ed6\u5df2\u8fde\u63a5\u5ba2\u6237\u7aef\u7684\u8bf7\u6c42\u3002<\/li>\n<\/ul>\n<p>\u8fd9\u79cd\u8bbe\u8ba1\u4f7f\u5f97 Redis \u5177\u5907\u4e86\u6781\u5f3a\u7684\u6269\u5c55\u6027&#xff0c;\u5f00\u53d1\u8005\u751a\u81f3\u53ef\u4ee5\u901a\u8fc7\u5b9e\u73b0\u65b0\u7684 ConnectionType \u6765\u8ba9 Redis \u652f\u6301\u5982 QUIC \u6216 HTTP\/3 \u7b49\u65b0\u578b\u534f\u8bae&#xff0c;\u800c\u65e0\u9700\u89e6\u52a8\u6838\u5fc3\u4e1a\u52a1\u4ee3\u7801\u3002<\/p>\n<p>  #mermaid-svg-ahZLT1ZzBsZYggrG{font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ahZLT1ZzBsZYggrG .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ahZLT1ZzBsZYggrG .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ahZLT1ZzBsZYggrG .error-icon{fill:#552222;}#mermaid-svg-ahZLT1ZzBsZYggrG .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ahZLT1ZzBsZYggrG .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ahZLT1ZzBsZYggrG .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ahZLT1ZzBsZYggrG .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ahZLT1ZzBsZYggrG .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ahZLT1ZzBsZYggrG .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ahZLT1ZzBsZYggrG .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ahZLT1ZzBsZYggrG .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ahZLT1ZzBsZYggrG .marker.cross{stroke:#333333;}#mermaid-svg-ahZLT1ZzBsZYggrG svg{font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ahZLT1ZzBsZYggrG p{margin:0;}#mermaid-svg-ahZLT1ZzBsZYggrG .label{font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;color:#333;}#mermaid-svg-ahZLT1ZzBsZYggrG .cluster-label text{fill:#333;}#mermaid-svg-ahZLT1ZzBsZYggrG .cluster-label span{color:#333;}#mermaid-svg-ahZLT1ZzBsZYggrG .cluster-label span p{background-color:transparent;}#mermaid-svg-ahZLT1ZzBsZYggrG .label text,#mermaid-svg-ahZLT1ZzBsZYggrG span{fill:#333;color:#333;}#mermaid-svg-ahZLT1ZzBsZYggrG .node rect,#mermaid-svg-ahZLT1ZzBsZYggrG .node circle,#mermaid-svg-ahZLT1ZzBsZYggrG .node ellipse,#mermaid-svg-ahZLT1ZzBsZYggrG .node polygon,#mermaid-svg-ahZLT1ZzBsZYggrG .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ahZLT1ZzBsZYggrG .rough-node .label text,#mermaid-svg-ahZLT1ZzBsZYggrG .node .label text,#mermaid-svg-ahZLT1ZzBsZYggrG .image-shape .label,#mermaid-svg-ahZLT1ZzBsZYggrG .icon-shape .label{text-anchor:middle;}#mermaid-svg-ahZLT1ZzBsZYggrG .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ahZLT1ZzBsZYggrG .rough-node .label,#mermaid-svg-ahZLT1ZzBsZYggrG .node .label,#mermaid-svg-ahZLT1ZzBsZYggrG .image-shape .label,#mermaid-svg-ahZLT1ZzBsZYggrG .icon-shape .label{text-align:center;}#mermaid-svg-ahZLT1ZzBsZYggrG .node.clickable{cursor:pointer;}#mermaid-svg-ahZLT1ZzBsZYggrG .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ahZLT1ZzBsZYggrG .arrowheadPath{fill:#333333;}#mermaid-svg-ahZLT1ZzBsZYggrG .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ahZLT1ZzBsZYggrG .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ahZLT1ZzBsZYggrG .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ahZLT1ZzBsZYggrG .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ahZLT1ZzBsZYggrG .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ahZLT1ZzBsZYggrG .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ahZLT1ZzBsZYggrG .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ahZLT1ZzBsZYggrG .cluster text{fill:#333;}#mermaid-svg-ahZLT1ZzBsZYggrG .cluster span{color:#333;}#mermaid-svg-ahZLT1ZzBsZYggrG div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ahZLT1ZzBsZYggrG .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ahZLT1ZzBsZYggrG rect.text{fill:none;stroke-width:0;}#mermaid-svg-ahZLT1ZzBsZYggrG .icon-shape,#mermaid-svg-ahZLT1ZzBsZYggrG .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ahZLT1ZzBsZYggrG .icon-shape p,#mermaid-svg-ahZLT1ZzBsZYggrG .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ahZLT1ZzBsZYggrG .icon-shape rect,#mermaid-svg-ahZLT1ZzBsZYggrG .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ahZLT1ZzBsZYggrG .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ahZLT1ZzBsZYggrG .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ahZLT1ZzBsZYggrG :root{&#8211;mermaid-font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;}#mermaid-svg-ahZLT1ZzBsZYggrG .ae_style&gt;*{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;color:#01579b!important;}#mermaid-svg-ahZLT1ZzBsZYggrG .ae_style span{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;color:#01579b!important;}#mermaid-svg-ahZLT1ZzBsZYggrG .ae_style tspan{fill:#01579b!important;}#mermaid-svg-ahZLT1ZzBsZYggrG .conn_style&gt;*{fill:#f3e5f5!important;stroke:#7b1fa2!important;stroke-width:2px!important;color:#7b1fa2!important;}#mermaid-svg-ahZLT1ZzBsZYggrG .conn_style span{fill:#f3e5f5!important;stroke:#7b1fa2!important;stroke-width:2px!important;color:#7b1fa2!important;}#mermaid-svg-ahZLT1ZzBsZYggrG .conn_style tspan{fill:#7b1fa2!important;}#mermaid-svg-ahZLT1ZzBsZYggrG .biz_style&gt;*{fill:#e8f5e9!important;stroke:#2e7d32!important;stroke-width:2px!important;color:#2e7d32!important;}#mermaid-svg-ahZLT1ZzBsZYggrG .biz_style span{fill:#e8f5e9!important;stroke:#2e7d32!important;stroke-width:2px!important;color:#2e7d32!important;}#mermaid-svg-ahZLT1ZzBsZYggrG .biz_style tspan{fill:#2e7d32!important;}#mermaid-svg-ahZLT1ZzBsZYggrG .highlight&gt;*{fill:#fff9c4!important;stroke:#fbc02d!important;stroke-width:2px!important;color:#92400e!important;}#mermaid-svg-ahZLT1ZzBsZYggrG .highlight span{fill:#fff9c4!important;stroke:#fbc02d!important;stroke-width:2px!important;color:#92400e!important;}#mermaid-svg-ahZLT1ZzBsZYggrG .highlight tspan{fill:#92400e!important;} <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>&#x1f4a1; Client \u4e1a\u52a1\u903b\u8f91\u5c42 &#8211; Application<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>&#x1f4e1; Connection \u62bd\u8c61\u5c42 &#8211; Transport<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>\u2699\ufe0f AE \u4e8b\u4ef6\u9a71\u52a8\u5f15\u64ce &#8211; Reactor<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/p>\n<p>\u65b0\u8fde\u63a5<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/p>\n<p>\u65e2\u6709\u6570\u636e<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/p>\n<p>TLS<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/p>\n<p>TCP<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/p>\n<p>\u672a\u5b8c\u6210<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/p>\n<p>\u63e1\u624b\u6210\u529f<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/p>\n<p>\u89e6\u53d1\u63e1\u624b\u8fed\u4ee3<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/p>\n<p>\u4e0b\u4e00\u6b21\u4e8b\u4ef6\u89e6\u53d1<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#01579b !important\" class=\"nodeLabel\"><\/p>\n<p>aeApiPoll() \u5524\u9192<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#01579b !important\" class=\"nodeLabel\"><\/p>\n<p>\u4e8b\u4ef6\u7c7b\u578b?<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#01579b !important\" class=\"nodeLabel\"><\/p>\n<p>acceptTcpHandler<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#01579b !important\" class=\"nodeLabel\"><\/p>\n<p>connHandleEvent<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#7b1fa2 !important\" class=\"nodeLabel\"><\/p>\n<p>connCreateAccept()<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#7b1fa2 !important\" class=\"nodeLabel\"><\/p>\n<p>\u4f20\u8f93\u534f\u8bae?<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#92400e !important\" class=\"nodeLabel\"><\/p>\n<p>&#x1f512; TLS \u63e1\u624b\u72b6\u6001\u673a<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#7b1fa2 !important\" class=\"nodeLabel\"><\/p>\n<p>\u2705 Connected \u72b6\u6001<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#7b1fa2 !important\" class=\"nodeLabel\"><\/p>\n<p>\u6ce8\u518c tlsHandshakeHandler<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#01579b !important\" class=\"nodeLabel\"><\/p>\n<p>\u9000\u51fa\u5e76\u4ea4\u8fd8\u63a7\u5236\u6743<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#2e7d32 !important\" class=\"nodeLabel\"><\/p>\n<p>createClient()<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#2e7d32 !important\" class=\"nodeLabel\"><\/p>\n<p>\u6ce8\u518c readQueryFromClient<\/p>\n<p><\/span> <\/p>\n<p>         <span style=\"color:#2e7d32 !important\" class=\"nodeLabel\"><\/p>\n<p>RESP \u534f\u8bae\u89e3\u6790 &amp; \u6267\u884c<\/p>\n<p><\/span> <\/p>\n<h2>\u7b2c\u56db\u90e8\u5206&#xff1a;\u547d\u4ee4\u8bfb\u53d6\u4e0e\u534f\u8bae\u89e3\u6790\u5168\u94fe\u8def\u5206\u6790<\/h2>\n<h3>4.1 \u8bfb\u4e8b\u4ef6\u56de\u8c03&#xff1a;readQueryFromClient \u7684\u6267\u884c\u65f6\u673a<\/h3>\n<p>\u5f53\u5ba2\u6237\u7aef\u53d1\u9001\u6570\u636e&#xff08;\u5982 SET \u547d\u4ee4&#xff09;\u5230\u8fbe\u5185\u6838\u7f13\u51b2\u533a&#xff0c;ae \u5f15\u64ce\u89e6\u53d1\u8bfb\u4e8b\u4ef6&#xff0c;\u8c03\u7528 readQueryFromClient\u3002\u4f46\u5728 8.4 \u4e2d&#xff0c;\u8fd9\u91cc\u5b58\u5728\u4e00\u4e2a\u6027\u80fd\u5206\u6c34\u5cad&#xff1a;<\/p>\n<h4>4.1.1 \u4e32\u884c\u4e0e\u5e76\u884c\u7684\u6289\u62e9<\/h4>\n<p>Redis 8.4 \u9ed8\u8ba4\u5728\u4e3b\u7ebf\u7a0b\u540c\u6b65\u5904\u7406\u8bfb\u8bf7\u6c42\u3002\u4f46\u5982\u679c\u5728 redis.conf \u4e2d\u5f00\u542f\u4e86 Threaded-IO&#xff1a;<\/p>\n<p>io-threads 4<br \/>\nio-threads-do-reads yes<\/p>\n<p>\u6e90\u7801\u903b\u8f91\u5982\u4e0b&#xff1a;<\/p>\n<p><span class=\"token comment\">\/* src\/networking.c *\/<\/span><br \/>\n<span class=\"token keyword\">void<\/span> <span class=\"token function\">readQueryFromClient<\/span><span class=\"token punctuation\">(<\/span>connection <span class=\"token operator\">*<\/span>conn<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    client <span class=\"token operator\">*<\/span>c <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">connGetPrivateData<\/span><span class=\"token punctuation\">(<\/span>conn<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token comment\">\/\/ \u6838\u5fc3\u903b\u8f91&#xff1a;\u5224\u65ad\u662f\u5426\u63a8\u8fdf\u8bfb\u53d6<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token function\">postponeClientRead<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">;<\/span> <\/p>\n<p>    <span class=\"token comment\">\/* \u5982\u679c\u4e0d\u6ee1\u8db3\u591a\u7ebf\u7a0b\u6761\u4ef6&#xff08;\u5982\u6570\u636e\u91cf\u6781\u5c0f&#xff09;&#xff0c;\u5219\u7acb\u5373\u6267\u884c\u540c\u6b65\u8bfb\u53d6 *\/<\/span><br \/>\n    <span class=\"token function\">readAndParse<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<ul>\n<li>\u6267\u884c\u65f6\u673a&#xff1a;\u5982\u679c\u6ee1\u8db3\u591a\u7ebf\u7a0b\u6761\u4ef6&#xff0c;\u4e3b\u7ebf\u7a0b\u4ec5\u5c06 c \u653e\u5165 server.clients_pending_read \u961f\u5217\u3002\u771f\u6b63\u7684 read() \u7cfb\u7edf\u8c03\u7528\u4f1a\u63a8\u8fdf\u5230 aeProcessEvents \u7684 beforesleep \u9636\u6bb5&#xff0c;\u7531 IO \u7ebf\u7a0b\u5e76\u884c\u6267\u884c\u3002<\/li>\n<\/ul>\n<h3>4.2 \u8f93\u5165\u7f13\u51b2\u533a\u7ba1\u7406&#xff1a;querybuf \u7684\u5206\u914d\u4e0e\u52a8\u6001\u6269\u5bb9\u7b56\u7565<\/h3>\n<p>\u65e0\u8bba\u662f\u4e3b\u7ebf\u7a0b\u8fd8\u662f IO \u7ebf\u7a0b&#xff0c;\u8bfb\u53d6\u5230\u7684\u539f\u59cb\u5b57\u8282 *3\\\\r\\\\n$3\\\\r\\\\nSET&#8230; \u90fd\u4f1a\u5b58\u5165\u5ba2\u6237\u7aef\u7684 c-&gt;querybuf \u4e2d\u3002<\/p>\n<h4>4.2.1 \u52a8\u6001\u4f38\u7f29\u673a\u5236<\/h4>\n<ul>\n<li>\u521d\u59cb\u5206\u914d&#xff1a;Redis \u503e\u5411\u4e8e\u4e00\u6b21\u8bfb\u53d6 PROTO_IOBUF_LEN&#xff08;16KB&#xff09;\u7684\u6570\u636e\u3002<\/li>\n<li>\u6269\u5bb9 (SDS \u903b\u8f91)&#xff1a;querybuf \u662f\u4e00\u4e2a SDS \u5b57\u7b26\u4e32\u3002\u901a\u8fc7 sdsMakeRoomFor \u4fdd\u8bc1\u7f13\u51b2\u533a\u6709\u8db3\u591f\u4f59\u91cf\u3002<\/li>\n<li>\u786c\u9650\u9632\u62a4&#xff1a;Redis 8.4 \u4e25\u683c\u9650\u5236 querybuf \u5927\u5c0f\u3002<span class=\"token comment\">\/* \u5982\u679c\u5ba2\u6237\u7aef\u6301\u7eed\u53d1\u9001\u6570\u636e\u4e14\u4e0d\u88ab\u89e3\u6790&#xff08;\u5982\u653b\u51fb&#xff09;&#xff0c;\u8d85\u8fc7 1GB \u5c06\u88ab\u5f3a\u5236\u5173\u95ed *\/<\/span><br \/>\n<span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token function\">sdslen<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>querybuf<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;<\/span> server<span class=\"token punctuation\">.<\/span>client_max_querybuf_len<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token function\">sdsfree<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>querybuf<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    c<span class=\"token operator\">-&gt;<\/span>querybuf <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">sdsempty<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token function\">freeClient<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span>\n <\/li>\n<\/ul>\n<h3>4.3 \u534f\u8bae\u89e3\u6790\u5f15\u64ce&#xff1a;resp_parser.c \u4e2d\u7684\u72b6\u6001\u673a\u5b9e\u73b0<\/h3>\n<p>\u5f53\u6570\u636e\u8fdb\u5165\u7f13\u51b2\u533a\u540e&#xff0c;processInputBuffer \u51fd\u6570\u542f\u52a8 RESP \u89e3\u6790\u5f15\u64ce\u3002<\/p>\n<h4>4.3.1 RESP2 \u4e0e RESP3 \u534f\u8bae\u7684\u517c\u5bb9\u5904\u7406<\/h4>\n<p>Redis 8.4 \u4f1a\u6839\u636e\u9996\u5b57\u8282\u81ea\u52a8\u8bc6\u522b\u534f\u8bae\u7c7b\u578b\u3002<\/p>\n<ul>\n<li>\u4ee5 SET name molaifeng \u4e3a\u4f8b&#xff1a;\n<li>\u89e3\u6790\u5668\u8bc6\u522b\u51fa *3\\\\r\\\\n&#xff0c;\u5224\u5b9a\u4e3a Multibulk&#xff08;\u6570\u7ec4&#xff09;\u6a21\u5f0f&#xff0c;\u8bbe\u7f6e c-&gt;multibulklen &#061; 3\u3002<\/li>\n<li>\u5206\u914d c-&gt;argv \u6307\u9488\u6570\u7ec4\u3002<\/li>\n<li>\u4f9d\u6b21\u8bfb\u53d6 $3\\\\r\\\\nSET\\\\r\\\\n\u3001$4\\\\r\\\\nname\\\\r\\\\n\u3001$9\\\\r\\\\nmolaifeng\\\\r\\\\n\u3002<\/li>\n<li>\u72b6\u6001\u673a\u8f6c\u79fb&#xff1a;\u89e3\u6790\u5668\u8bb0\u5f55\u5f53\u524d\u8bfb\u53d6\u7684\u504f\u79fb\u91cf c-&gt;qb_pos\u3002\u5982\u679c\u6570\u636e\u4e0d\u5b8c\u6574&#xff08;\u5982\u53ea\u6536\u5230\u4e00\u534a&#xff09;&#xff0c;\u72b6\u6001\u673a\u4f1a\u4fdd\u7559\u5f53\u524d\u8fdb\u5ea6&#xff0c;\u9000\u51fa\u89e3\u6790&#xff0c;\u7b49\u5f85\u4e0b\u6b21\u8bfb\u4e8b\u4ef6\u89e6\u53d1\u3002<\/li>\n<\/li>\n<\/ul>\n<h4>4.3.2 \u5185\u8054\u547d\u4ee4&#xff08;Inline Commands&#xff09;\u7684\u7279\u6b8a\u89e3\u6790<\/h4>\n<p>\u5982\u679c\u7528\u6237\u901a\u8fc7 telnet \u76f4\u63a5\u8f93\u5165 PING\\\\r\\\\n&#xff08;\u975e * \u5f00\u5934&#xff09;&#xff0c;Redis \u4f1a\u8fdb\u5165 processInlineBuffer\u3002<\/p>\n<ul>\n<li>\u5b83\u4f7f\u7528\u7a7a\u683c\u5206\u5272\u5b57\u7b26\u4e32&#xff0c;\u5c06 PING \u8f6c\u6362\u4e3a c-&gt;argv[0]\u3002<\/li>\n<li>\u6ce8\u610f&#xff1a;\u5185\u8054\u547d\u4ee4\u4e3b\u8981\u7528\u4e8e\u8c03\u8bd5&#xff0c;\u751f\u4ea7\u73af\u5883\u4e0b\u9ad8\u6027\u80fd\u5ba2\u6237\u7aef\u5747\u4f7f\u7528\u6807\u51c6\u7684 Multibulk \u534f\u8bae\u3002<\/li>\n<\/ul>\n<h3>4.4 \u547d\u4ee4\u67e5\u627e&#xff1a;lookupCommand \u4e0e\u54c8\u5e0c\u8868\u68c0\u7d22<\/h3>\n<p>\u5f53 c-&gt;argv \u88ab\u586b\u5145\u5b8c\u6bd5&#xff08;\u5373 argc&#061;3, argv&#061;[&#034;SET&#034;, &#034;name&#034;, &#034;molaifeng&#034;]&#xff09;&#xff0c;\u89e3\u6790\u9636\u6bb5\u5ba3\u544a\u7ed3\u675f&#xff0c;\u8fdb\u5165\u6267\u884c\u51c6\u5907\u9636\u6bb5\u3002<\/p>\n<h4>4.4.1 \u54c8\u5e0c\u8868\u68c0\u7d22<\/h4>\n<p>Redis \u5728\u5168\u5c40 server.commands \u5b57\u5178\u4e2d\u67e5\u627e\u7b2c\u4e00\u4e2a\u53c2\u6570&#xff1a;<\/p>\n<p><span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">redisCommand<\/span> <span class=\"token operator\">*<\/span><span class=\"token function\">lookupCommand<\/span><span class=\"token punctuation\">(<\/span>sds name<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token function\">dictFetchValue<\/span><span class=\"token punctuation\">(<\/span>server<span class=\"token punctuation\">.<\/span>commands<span class=\"token punctuation\">,<\/span> name<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<ul>\n<li>\u5bf9\u4e8e SET&#xff0c;\u5b83\u8fd4\u56de\u4e00\u4e2a\u6307\u5411 setCommand \u7ed3\u6784\u7684\u6307\u9488\u3002\u8be5\u7ed3\u6784\u5305\u542b\u4e86\u8be5\u547d\u4ee4\u7684\u5c5e\u6027&#xff1a;\u5982 flags&#xff08;\u5199\u547d\u4ee4\u3001\u539f\u5b50\u6027&#xff09;\u3001arity&#xff08;\u53c2\u6570\u4e2a\u6570\u8981\u6c42&#xff09;\u3002<\/li>\n<\/ul>\n<h4>4.4.2 \u5168\u94fe\u8def\u6700\u7ec8\u6b65\u9aa4&#xff1a;\u547d\u4ee4\u5206\u53d1 (Dispatch)<\/h4>\n<p>\u627e\u5230\u547d\u4ee4\u540e&#xff0c;\u4e3b\u7ebf\u7a0b\u4f1a\u8fdb\u884c\u6700\u540e\u51e0\u9879\u5173\u952e\u68c0\u67e5&#xff0c;\u8fd9\u4e5f\u662f 8.4 \u5b89\u5168\u6027\u7684\u4f53\u73b0&#xff1a;<\/p>\n<li>\u53c2\u6570\u6821\u9a8c&#xff1a;SET \u547d\u4ee4\u53c2\u6570\u5fc5\u987b <span class=\"katex--inline\"><span class=\"katex\"><span class=\"katex-mathml\">\n<p>          \u2265 <\/p>\n<p>          3 <\/p>\n<p>         \\\\ge 3 <\/p>\n<p>     <\/span><span class=\"katex-html\"><span class=\"base\"><span class=\"strut\" style=\"height: 0.7719em;vertical-align: -0.136em\"><\/span><span class=\"mrel\">\u2265<\/span><span class=\"mspace\" style=\"margin-right: 0.2778em\"><\/span><\/span><span class=\"base\"><span class=\"strut\" style=\"height: 0.6444em\"><\/span><span class=\"mord\">3<\/span><\/span><\/span><\/span><\/span>\u3002<\/li>\n<li>ACL \u6743\u9650&#xff1a;\u68c0\u67e5\u5f53\u524d User \u662f\u5426\u6709 SET \u6743\u9650&#xff0c;\u4ee5\u53ca\u5bf9 Key name \u662f\u5426\u6709\u5199\u6743\u9650\u3002<\/li>\n<li>\u5185\u5b58\u72b6\u6001&#xff1a;\u82e5\u662f\u5199\u547d\u4ee4\u4e14 maxmemory \u5df2\u6ee1&#xff0c;\u7acb\u5373\u89e6\u53d1 performEvictions\u3002<\/li>\n<li>\u6267\u884c&#xff1a;<span class=\"token comment\">\/* \u6838\u5fc3\u8c03\u7528 *\/<\/span><br \/>\nc<span class=\"token operator\">-&gt;<\/span>cmd<span class=\"token operator\">-&gt;<\/span><span class=\"token function\">proc<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u6b64\u65f6\u8df3\u8f6c\u81f3 setCommand \u51fd\u6570<\/span><br \/>\n setCommand \u968f\u540e\u8c03\u7528\u5e95\u5c42 dbAdd \u51fd\u6570&#xff0c;\u5c06 &#034;name&#034; \u548c &#034;molaifeng&#034; \u5199\u5165\u5168\u5c40\u54c8\u5e0c\u8868\u3002<\/li>\n<h3>4.5 \u6848\u4f8b\u603b\u7ed3&#xff1a;SET name molaifeng \u7684\u5168\u65c5\u7a0b<\/h3>\n<li>\u6d41\u5165&#xff1a;\u5185\u6838\u6536\u5230\u6570\u636e -&gt; ae \u89e6\u53d1 readQueryFromClient -&gt; &#xff08;\u82e5\u5f00\u542f TIO&#xff09;\u653e\u5165 Pending \u961f\u5217\u3002<\/li>\n<li>\u7f13\u51b2&#xff1a;\u6570\u636e\u88ab\u5199\u5165 querybuf&#xff0c;\u5982\u679c\u7f13\u51b2\u533a\u4e0d\u591f\u5927&#xff0c;SDS \u81ea\u52a8\u6269\u5bb9\u3002<\/li>\n<li>\u62c6\u89e3&#xff1a;\u72b6\u6001\u673a\u9010\u5b57\u8282\u626b\u63cf&#xff0c;\u5c06 *3&#8230; \u62c6\u89e3\u4e3a 3 \u4e2a robj \u5bf9\u8c61\u5b58\u5165 c-&gt;argv\u3002<\/li>\n<li>\u5bfb\u5f84&#xff1a;lookupCommand \u5728 O(1) \u65f6\u95f4\u5185\u4ece\u54c8\u5e0c\u8868\u627e\u5230 SET \u6307\u4ee4\u3002<\/li>\n<li>\u843d\u5730&#xff1a;\u7ecf\u8fc7 ACL \u548c\u5185\u5b58\u6821\u9a8c&#xff0c;\u4e3b\u7ebf\u7a0b\u6267\u884c setCommand&#xff0c;\u6570\u636e\u5b58\u5165\u5185\u5b58\u5b57\u5178\u3002<\/li>\n<li>\u53cd\u9988&#xff1a;addReply \u5c06 &#043;OK\\\\r\\\\n \u5199\u5165\u5ba2\u6237\u7aef\u8f93\u51fa\u7f13\u51b2\u533a&#xff0c;\u7b49\u5f85\u53d1\u9001\u3002<\/li>\n<p>\u8fd9\u79cd\u8bbe\u8ba1\u786e\u4fdd\u4e86 Redis \u5373\u4f7f\u5728\u5904\u7406\u6781\u5176\u590d\u6742\u7684 RESP3 \u5d4c\u5957\u534f\u8bae\u65f6&#xff0c;\u4f9d\u7136\u80fd\u4fdd\u6301 O(1) \u7ea7\u522b\u7684\u89e3\u6790\u6027\u80fd\u3002<\/p>\n<p>      Dict (Memory) <\/p>\n<p>      Main Thread (Redis Core) <\/p>\n<p>      IO Thread (8.4) <\/p>\n<p>      Client (molaifeng) <\/p>\n<p>       Dict (Memory) <\/p>\n<p>       Main Thread (Redis Core) <\/p>\n<p>       IO Thread (8.4) <\/p>\n<p>       Client (molaifeng) <\/p>\n<p>  #mermaid-svg-UmlZg1ynmR7xwXJu{font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-UmlZg1ynmR7xwXJu .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-UmlZg1ynmR7xwXJu .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-UmlZg1ynmR7xwXJu .error-icon{fill:#552222;}#mermaid-svg-UmlZg1ynmR7xwXJu .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-UmlZg1ynmR7xwXJu .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-UmlZg1ynmR7xwXJu .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-UmlZg1ynmR7xwXJu .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-UmlZg1ynmR7xwXJu .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-UmlZg1ynmR7xwXJu .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-UmlZg1ynmR7xwXJu .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-UmlZg1ynmR7xwXJu .marker{fill:#333333;stroke:#333333;}#mermaid-svg-UmlZg1ynmR7xwXJu .marker.cross{stroke:#333333;}#mermaid-svg-UmlZg1ynmR7xwXJu svg{font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-UmlZg1ynmR7xwXJu p{margin:0;}#mermaid-svg-UmlZg1ynmR7xwXJu .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-UmlZg1ynmR7xwXJu text.actor&gt;tspan{fill:black;stroke:none;}#mermaid-svg-UmlZg1ynmR7xwXJu .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-UmlZg1ynmR7xwXJu .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-UmlZg1ynmR7xwXJu .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-UmlZg1ynmR7xwXJu .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-UmlZg1ynmR7xwXJu #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-UmlZg1ynmR7xwXJu .sequenceNumber{fill:white;}#mermaid-svg-UmlZg1ynmR7xwXJu #sequencenumber{fill:#333;}#mermaid-svg-UmlZg1ynmR7xwXJu #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-UmlZg1ynmR7xwXJu .messageText{fill:#333;stroke:none;}#mermaid-svg-UmlZg1ynmR7xwXJu .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-UmlZg1ynmR7xwXJu .labelText,#mermaid-svg-UmlZg1ynmR7xwXJu .labelText&gt;tspan{fill:black;stroke:none;}#mermaid-svg-UmlZg1ynmR7xwXJu .loopText,#mermaid-svg-UmlZg1ynmR7xwXJu .loopText&gt;tspan{fill:black;stroke:none;}#mermaid-svg-UmlZg1ynmR7xwXJu .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-UmlZg1ynmR7xwXJu .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-UmlZg1ynmR7xwXJu .noteText,#mermaid-svg-UmlZg1ynmR7xwXJu .noteText&gt;tspan{fill:black;stroke:none;}#mermaid-svg-UmlZg1ynmR7xwXJu .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-UmlZg1ynmR7xwXJu .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-UmlZg1ynmR7xwXJu .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-UmlZg1ynmR7xwXJu .actorPopupMenu{position:absolute;}#mermaid-svg-UmlZg1ynmR7xwXJu .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 \/ 0.4));}#mermaid-svg-UmlZg1ynmR7xwXJu .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-UmlZg1ynmR7xwXJu .actor-man circle,#mermaid-svg-UmlZg1ynmR7xwXJu line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-UmlZg1ynmR7xwXJu :root{&#8211;mermaid-font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;} <\/p>\n<p>      beforesleep \u9636\u6bb5 <\/p>\n<p>      \u4e0b\u4e00\u6b21 beforesleep <\/p>\n<p>    \u53d1\u9001 *3\\\\r\\\\n$3\\\\r\\\\nSET&#8230; <\/p>\n<p>    readQueryFromClient (\u52a0\u5165\u7b49\u5f85\u961f\u5217) <\/p>\n<p>    \u5e76\u884c\u6267\u884c read() \u5e76\u89e3\u6790\u534f\u8bae <\/p>\n<p>    lookupCommand(&#034;SET&#034;) <\/p>\n<p>    ACL &amp; Memory Check <\/p>\n<p>    setCommand -&gt;&gt; dbAdd(&#034;name&#034;, &#034;molaifeng&#034;) <\/p>\n<p>    addReply(shared.ok) <\/p>\n<p>    \u53d1\u9001 &#043;OK\\\\r\\\\n <\/p>\n<h2>\u7b2c\u4e94\u90e8\u5206&#xff1a;\u591a\u7ebf\u7a0b IO&#xff08;Threaded IO&#xff09;\u7684\u5e76\u53d1\u534f\u4f5c\u673a\u5236<\/h2>\n<p>\u5728 Redis 8.4 \u4e2d&#xff0c;\u7f51\u7edc\u6a21\u578b\u7ecf\u5386\u4e86\u81ea\u5f15\u5165\u591a\u7ebf\u7a0b\u4ee5\u6765\u6700\u5f7b\u5e95\u7684\u91cd\u6784\u3002\u67b6\u6784\u4ece Redis 6.0\/7.0 \u7684 \u201c\u4e3b\u7ebf\u7a0b EventLoop &#043; Worker \u8f85\u52a9\u7f16\u89e3\u7801\u201d \u6f14\u8fdb\u4e3a \u201cOne EventLoop Per Thread&#xff08;\u6bcf\u7ebf\u7a0b\u4e00\u4e8b\u4ef6\u5faa\u73af&#xff09;\u201d\u3002<\/p>\n<p>\u5982\u679c\u4e0d\u7406\u89e3\u8fd9\u4e2a\u6839\u672c\u6027\u7684\u53d8\u5316&#xff0c;\u53ef\u4ee5\u5c06\u5176\u6bd4\u4f5c\u9910\u5385\u6539\u9769&#xff1a;<\/p>\n<ul>\n<li>\u65e7\u6a21\u5f0f&#xff08;Redis 6\/7&#xff09;&#xff1a;\u4e3b\u7ebf\u7a0b\u662f\u201c\u5305\u5de5\u5934\u201d&#xff0c;\u65e2\u8981\u901a\u8fc7\u552f\u4e00\u7684 epoll \u76ef\u7740\u6240\u6709\u5ba2\u4eba\u7684\u4e3e\u624b&#xff08;IO \u4e8b\u4ef6&#xff09;&#xff0c;\u53c8\u8981\u8d1f\u8d23\u7092\u83dc&#xff08;\u6267\u884c\u547d\u4ee4&#xff09;\u3002IO \u7ebf\u7a0b\u53ea\u662f\u4e34\u65f6\u5de5&#xff0c;\u5305\u5de5\u5934\u628a\u8bfb\u5230\u7684\u6570\u636e\u585e\u7ed9\u4ed6\u4eec\u89e3\u538b&#xff0c;\u89e3\u538b\u5b8c\u8fd8\u5f97\u5305\u5de5\u5934\u81ea\u5df1\u5904\u7406\u3002<\/li>\n<li>\u65b0\u6a21\u5f0f&#xff08;Redis 8.4&#xff09;&#xff1a;\u4e3b\u7ebf\u7a0b\u5347\u804c\u4e3a\u201c\u53a8\u5e08\u957f\u201d&#xff0c;\u53ea\u8d1f\u8d23\u7092\u83dc&#xff08;\u5185\u5b58\u64cd\u4f5c&#xff09;\u3002IO \u7ebf\u7a0b\u53d8\u6210\u4e86\u62e5\u6709\u72ec\u7acb\u5730\u76d8&#xff08;EventLoop&#xff09;\u7684\u201c\u5168\u804c\u670d\u52a1\u5458\u201d\u3002\u5ba2\u4eba\u4e00\u8fdb\u95e8&#xff0c;\u5c31\u5206\u914d\u7ed9\u67d0\u4e2a\u670d\u52a1\u5458&#xff0c;\u4ece\u6b64\u4ee5\u540e\u8fd9\u4e2a\u5ba2\u4eba\u7684\u70b9\u83dc&#xff08;Read&#xff09;\u3001\u5012\u6c34&#xff08;Ping\/Pong&#xff09;\u3001\u7ed3\u8d26&#xff08;Write&#xff09;\u5168\u7531\u670d\u52a1\u5458\u72ec\u7acb\u8d1f\u8d23&#xff0c;\u53ea\u6709\u4e0b\u5355\u90a3\u4e00\u523b\u624d\u4e0e\u53a8\u5e08\u957f\u4ea4\u4e92\u3002<\/li>\n<\/ul>\n<h3>5.1 IO \u7ebf\u7a0b\u6c60\u7684\u521d\u59cb\u5316&#xff1a;\u6784\u5efa\u72ec\u7acb Reactor<\/h3>\n<p>\u521d\u59cb\u5316\u4e0d\u518d\u4ec5\u4ec5\u662f\u542f\u52a8\u7ebf\u7a0b&#xff0c;\u800c\u662f\u4e3a\u6bcf\u4e2a Worker \u7ebf\u7a0b\u6784\u5efa\u4e00\u4e2a\u72ec\u7acb\u7684 Reactor \u6a21\u578b\u3002<\/p>\n<p>\u6e90\u7801\u5b9e\u8bc1 (src\/iothread.c &#8211; initThreadedIO)&#xff1a;<\/p>\n<p><span class=\"token keyword\">void<\/span> <span class=\"token function\">initThreadedIO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">void<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    server<span class=\"token punctuation\">.<\/span>io_threads_active <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token comment\">\/\/ &#8230;<\/span><br \/>\n    <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token keyword\">int<\/span> i <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">;<\/span> i <span class=\"token operator\">&lt;<\/span> server<span class=\"token punctuation\">.<\/span>io_threads_num<span class=\"token punctuation\">;<\/span> i<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        IOThread <span class=\"token operator\">*<\/span>t <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>IOThreads<span class=\"token punctuation\">[<\/span>i<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/* [\u6838\u5fc3\u53d8\u9769] 1. \u4e3a\u6bcf\u4e2a\u7ebf\u7a0b\u521b\u5efa\u72ec\u7acb\u7684 EventLoop *\/<\/span><br \/>\n        <span class=\"token comment\">\/* \u8fd9\u610f\u5473\u7740 IO \u7ebf\u7a0b\u62e5\u6709\u4e86\u81ea\u5df1\u7684 epoll \u5b9e\u4f8b&#xff0c;\u53ef\u4ee5\u72ec\u7acb\u76d1\u542c fd *\/<\/span><br \/>\n        t<span class=\"token operator\">-&gt;<\/span>el <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">aeCreateEventLoop<\/span><span class=\"token punctuation\">(<\/span>server<span class=\"token punctuation\">.<\/span>maxclients<span class=\"token operator\">&#043;<\/span>CONFIG_FDSET_INCR<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/* 2. \u5efa\u7acb\u901a\u4fe1\u7ba1\u9053 (Pipe\/EventFD) *\/<\/span><br \/>\n        <span class=\"token comment\">\/* \u4e5f\u5c31\u662f\u201c\u5185\u7ebf\u7535\u8bdd\u201d&#xff0c;\u7528\u4e8e\u4e3b\u7ebf\u7a0b\u5524\u9192\u6c89\u7761\u7684 IO \u7ebf\u7a0b *\/<\/span><br \/>\n        t<span class=\"token operator\">-&gt;<\/span>pending_clients_notifier <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">createEventNotifier<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token function\">aeCreateFileEvent<\/span><span class=\"token punctuation\">(<\/span>t<span class=\"token operator\">-&gt;<\/span>el<span class=\"token punctuation\">,<\/span> <span class=\"token function\">getReadEventFd<\/span><span class=\"token punctuation\">(<\/span>t<span class=\"token operator\">-&gt;<\/span>pending_clients_notifier<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                          AE_READABLE<span class=\"token punctuation\">,<\/span> handleClientsFromMainThread<span class=\"token punctuation\">,<\/span> t<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/* 3. \u542f\u52a8\u7ebf\u7a0b&#xff0c;\u8fdb\u5165\u72ec\u7acb\u7684\u4e8b\u4ef6\u5faa\u73af *\/<\/span><br \/>\n        <span class=\"token function\">pthread_create<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>t<span class=\"token operator\">-&gt;<\/span>tid<span class=\"token punctuation\">,<\/span> <span class=\"token constant\">NULL<\/span><span class=\"token punctuation\">,<\/span> IOThreadMain<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token keyword\">void<\/span><span class=\"token operator\">*<\/span><span class=\"token punctuation\">)<\/span>t<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u89e3\u6790&#xff1a; \u4ee3\u7801\u4e2d\u7684 aeCreateEventLoop \u662f\u6700\u786e\u51ff\u7684\u8bc1\u636e\u3002\u6bcf\u4e2a IO \u7ebf\u7a0b\u73b0\u5728\u90fd\u662f\u4e00\u4e2a\u72ec\u7acb\u7684 Reactor&#xff0c;\u901a\u8fc7 epoll_wait \u72ec\u7acb\u7ba1\u7406\u5176\u8f96\u533a\u5185\u7684\u8fde\u63a5&#xff0c;\u5f7b\u5e95\u6253\u7834\u4e86\u4e3b\u7ebf\u7a0b\u7684\u5355\u70b9\u74f6\u9888\u3002<\/p>\n<h3>5.2 \u4efb\u52a1\u5206\u53d1&#xff1a;\u8fde\u63a5\u5378\u8f7d&#xff08;Connection Offloading&#xff09;<\/h3>\n<p>\u4efb\u52a1\u5206\u53d1\u7684\u672c\u8d28\u53d8\u6210\u4e86\u201c\u8fde\u63a5\u8fc7\u6237\u201d\u3002\u5f53\u65b0\u8fde\u63a5\u5efa\u7acb\u65f6&#xff0c;\u4e3b\u7ebf\u7a0b\u4f1a\u5c06\u8fde\u63a5\u7684\u6240\u6709\u6743&#xff08;Ownership&#xff09;\u6c38\u4e45\u6027\u5730\u79fb\u4ea4\u7ed9 IO \u7ebf\u7a0b\u3002<\/p>\n<p>\u6d41\u7a0b\u903b\u8f91&#xff1a;<\/p>\n<li>\u8fce\u5bbe&#xff1a;\u4e3b\u7ebf\u7a0b accept \u65b0\u8fde\u63a5\u3002<\/li>\n<li>\u8fc7\u6237&#xff1a;\u4e3b\u7ebf\u7a0b\u5c06\u8fde\u63a5\u4ece\u81ea\u5df1\u7684 epoll \u4e2d\u79fb\u9664&#xff08;Unbind&#xff09;&#xff0c;\u5e76\u5728\u5185\u5b58\u4e2d\u6807\u8bb0\u201c\u8fd9\u4e2a\u8fde\u63a5\u5f52 3 \u53f7\u7ebf\u7a0b\u7ba1\u201d\u3002<\/li>\n<li>\u63a5\u7ba1&#xff1a;3 \u53f7\u7ebf\u7a0b\u88ab\u5524\u9192&#xff0c;\u5c06\u8fde\u63a5\u7ed1\u5b9a\u5230\u81ea\u5df1\u7684 epoll \u4e2d&#xff08;Rebind&#xff09;\u3002<\/li>\n<p>\u6e90\u7801\u5b9e\u8bc1 (src\/iothread.c)&#xff1a;<\/p>\n<p><span class=\"token comment\">\/* \u4e3b\u7ebf\u7a0b\u6267\u884c&#xff1a;\u7529\u9505 *\/<\/span><br \/>\n<span class=\"token keyword\">void<\/span> <span class=\"token function\">assignClientToIOThread<\/span><span class=\"token punctuation\">(<\/span>client <span class=\"token operator\">*<\/span>c<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/ 1. \u8d1f\u8f7d\u5747\u8861\u7b97\u6cd5\u9009\u51fa\u6700\u7a7a\u95f2\u7ebf\u7a0b<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> min_id <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">;<\/span> <\/p>\n<p>    <span class=\"token comment\">\/\/ 2. [\u5173\u952e] \u4ece\u4e3b\u7ebf\u7a0b EventLoop \u89e3\u7ed1&#xff0c;\u505c\u6b62\u76d1\u542c\u8be5 fd<\/span><br \/>\n    <span class=\"token function\">connUnbindEventLoop<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>conn<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ 3. \u653e\u5165\u961f\u5217&#xff0c;\u51c6\u5907\u79fb\u4ea4<\/span><br \/>\n    c<span class=\"token operator\">-&gt;<\/span>io_flags <span class=\"token operator\">&amp;&#061;<\/span> <span class=\"token operator\">~<\/span><span class=\"token punctuation\">(<\/span>CLIENT_IO_READ_ENABLED <span class=\"token operator\">|<\/span> CLIENT_IO_WRITE_ENABLED<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token function\">listAddNodeTail<\/span><span class=\"token punctuation\">(<\/span>mainThreadPendingClientsToIOThreads<span class=\"token punctuation\">[<\/span>c<span class=\"token operator\">-&gt;<\/span>tid<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span> c<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/* IO \u7ebf\u7a0b\u6267\u884c&#xff1a;\u63a5\u7ba1 *\/<\/span><br \/>\n<span class=\"token keyword\">int<\/span> <span class=\"token function\">processClientsFromMainThread<\/span><span class=\"token punctuation\">(<\/span>IOThread <span class=\"token operator\">*<\/span>t<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/ &#8230; \u904d\u5386\u961f\u5217 &#8230;<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span><span class=\"token function\">connHasEventLoop<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>conn<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ 4. [\u5173\u952e] \u7ed1\u5b9a\u5230 IO \u7ebf\u7a0b\u81ea\u5df1\u7684 EventLoop<\/span><br \/>\n        <span class=\"token function\">connRebindEventLoop<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>conn<span class=\"token punctuation\">,<\/span> t<span class=\"token operator\">-&gt;<\/span>el<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token function\">connSetReadHandler<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>conn<span class=\"token punctuation\">,<\/span> readQueryFromClient<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>\u6df1\u5ea6\u67b6\u6784\u5206\u6790&#xff1a;Syscall \u5f00\u9500\u4e0e\u6027\u80fd\u6743\u8861&#xff08;Trade-off&#xff09;<\/h4>\n<p>\u4f60\u53ef\u80fd\u4f1a\u654f\u9510\u5730\u53d1\u73b0&#xff1a;connUnbind \u548c connRebind \u5b9e\u9645\u4e0a\u5bf9\u5e94\u7740\u5e95\u5c42\u7684 epoll_ctl(DEL) \u548c epoll_ctl(ADD) \u7cfb\u7edf\u8c03\u7528\u3002\u8fd9\u662f\u5426\u4f1a\u5bfc\u81f4\u6027\u80fd\u95ee\u9898&#xff1f;<\/p>\n<li>\n<p>Syscall \u5f00\u9500\u786e\u5b9e\u5b58\u5728&#xff1a; \u5728\u8fde\u63a5\u79fb\u4ea4\u7684\u8fc7\u7a0b\u4e2d&#xff0c;\u786e\u5b9e\u591a\u51fa\u4e86\u4e24\u6b21\u7cfb\u7edf\u8c03\u7528\u548c\u4e00\u6b21\u8de8\u7ebf\u7a0b\u4e0a\u4e0b\u6587\u5207\u6362\u3002\u5982\u679c\u662f\u5728\u77ed\u8fde\u63a5\u9ad8\u5e76\u53d1&#xff08;High CPS&#xff09;\u573a\u666f\u4e0b&#xff08;\u4f8b\u5982 PHP \u77ed\u8fde\u63a5\u9891\u7e41\u91cd\u8fde&#xff09;&#xff0c;\u8fd9\u4f1a\u5bfc\u81f4 System CPU \u8f7b\u5fae\u4e0a\u5347\u3002<\/p>\n<\/li>\n<li>\n<p>\u4e3a\u4ec0\u4e48\u8fd8\u8981\u8fd9\u4e48\u8bbe\u8ba1&#xff1f;&#xff08;\u6361\u897f\u74dc\u4e22\u829d\u9ebb&#xff09;<\/p>\n<ul>\n<li>\u8ba1\u7b97\u5bc6\u96c6\u578b\u5378\u8f7d&#xff1a;Redis \u7684\u6027\u80fd\u74f6\u9888\u901a\u5e38\u4e0d\u5728\u4e8e\u8fde\u63a5\u5efa\u7acb&#xff0c;\u800c\u5728\u4e8e\u8bf7\u6c42\u5904\u7406\u9636\u6bb5\u7684\u534f\u8bae\u89e3\u6790&#xff08;Protocol Parsing&#xff09;\u548c\u5185\u5b58\u62f7\u8d1d\u3002\u5c06\u8fd9\u90e8\u5206\u7e41\u91cd\u7684 CPU \u6d88\u8017\u5206\u644a\u7ed9 IO \u7ebf\u7a0b&#xff0c;\u5176\u6536\u76ca\u8fdc\u5927\u4e8e\u8fde\u63a5\u5efa\u7acb\u65f6\u7684\u5c11\u91cf Syscall \u635f\u8017\u3002<\/li>\n<li>\u5185\u5b58\u5b89\u5168&#xff1a;epoll_ctl \u64cd\u4f5c\u4ec5\u6d89\u53ca\u5185\u6838\u7ea2\u9ed1\u6811\u8282\u70b9\u7684\u6307\u9488\u8c03\u6574&#xff0c;\u4e0d\u4f1a\u5bfc\u81f4\u5185\u5b58\u98d9\u5347\u3002\u5185\u5b58\u6d88\u8017\u4e3b\u8981\u53d6\u51b3\u4e8e Client \u5bf9\u8c61\u7684\u6570\u91cf&#xff08;\u8fde\u63a5\u6570&#xff09;&#xff0c;\u8fd9\u5728\u5355\u7ebf\u7a0b\u6a21\u578b\u4e2d\u4e5f\u662f\u4e00\u6837\u7684\u3002<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u6700\u4f73\u5b9e\u8df5\u5efa\u8bae&#xff1a; \u4e3a\u4e86\u6700\u5927\u5316 Redis 8.4 \u7684\u6027\u80fd&#xff0c;\u5f3a\u70c8\u5efa\u8bae\u4f7f\u7528\u8fde\u63a5\u6c60&#xff08;Connection Pooling&#xff09;\u3002\u901a\u8fc7\u4fdd\u6301\u957f\u8fde\u63a5&#xff0c;\u5c06\u4e00\u6b21\u201c\u8fc7\u6237\u201d\u7684\u5f00\u9500\u5206\u644a\u5230\u540e\u7eed\u6210\u5343\u4e0a\u4e07\u6b21\u7684\u8bf7\u6c42\u5904\u7406\u4e2d&#xff0c;\u4ece\u800c\u5b9e\u73b0\u63a5\u8fd1\u7ebf\u6027\u7684\u541e\u5410\u91cf\u589e\u957f\u3002<\/p>\n<\/li>\n<h3>5.3 \u534f\u4f5c\u673a\u5236&#xff1a;\u72b6\u6001\u4f4d\u9a71\u52a8\u7684\u8bfb\u5199\u5206\u79bb<\/h3>\n<p>\u65e2\u7136\u8fde\u63a5\u5728 IO \u7ebf\u7a0b\u624b\u91cc&#xff0c;\u6570\u636e\u4e5f\u5728 IO \u7ebf\u7a0b\u624b\u91cc&#xff0c;\u4e3b\u7ebf\u7a0b\u5982\u4f55\u6267\u884c\u547d\u4ee4&#xff1f;Redis 8.4 \u8bbe\u8ba1\u4e86\u4e00\u5957\u7cbe\u5bc6\u7684\u961f\u5217\u4ea4\u6362\u534f\u8bae\u3002<\/p>\n<h4>\u9636\u6bb5\u4e00&#xff1a;\u670d\u52a1\u5458\u70b9\u83dc&#xff08;IO Thread Read&#xff09;<\/h4>\n<p>IO \u7ebf\u7a0b\u72ec\u7acb\u76d1\u542c Socket \u53ef\u8bfb\u4e8b\u4ef6&#xff0c;\u8c03\u7528 readQueryFromClient \u8bfb\u53d6\u5e76\u89e3\u6790\u534f\u8bae\u3002\u6b64\u65f6\u4e3b\u7ebf\u7a0b\u5b8c\u5168\u4e0d\u77e5\u60c5\u3002 \u4e00\u65e6\u89e3\u6790\u51fa\u5b8c\u6574\u547d\u4ee4&#xff0c;IO \u7ebf\u7a0b\u505c\u6b62\u5904\u7406&#xff0c;\u7533\u8bf7\u201c\u4e0a\u62a5\u201d\u3002<\/p>\n<p><span class=\"token comment\">\/* src\/networking.c *\/<\/span><br \/>\n<span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>running_tid <span class=\"token operator\">!&#061;<\/span> IOTHREAD_MAIN_THREAD_ID<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/* \u6807\u8bb0&#xff1a;\u6709\u547d\u4ee4\u9700\u8981\u6267\u884c *\/<\/span><br \/>\n    c<span class=\"token operator\">-&gt;<\/span>io_flags <span class=\"token operator\">|&#061;<\/span> CLIENT_IO_PENDING_COMMAND<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token comment\">\/* \u653e\u5165\u201c\u5f85\u5904\u7406\u201d\u961f\u5217&#xff0c;\u5e76\u901a\u77e5\u4e3b\u7ebf\u7a0b *\/<\/span><br \/>\n    <span class=\"token function\">enqueuePendingClientsToMainThread<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>\u9636\u6bb5\u4e8c&#xff1a;\u53a8\u5e08\u7092\u83dc&#xff08;Main Thread Execute&#xff09;<\/h4>\n<p>\u4e3b\u7ebf\u7a0b\u6536\u5230\u901a\u77e5&#xff0c;\u4e34\u65f6\u63a5\u7ba1 Client \u5bf9\u8c61&#xff0c;\u6267\u884c\u6838\u5fc3\u903b\u8f91&#xff08;\u64cd\u4f5c\u5b57\u5178\u3001\u5199 AOF \u7b49&#xff09;\u3002<\/p>\n<p><span class=\"token comment\">\/* src\/iothread.c *\/<\/span><br \/>\n<span class=\"token keyword\">int<\/span> <span class=\"token function\">processClientsFromIOThread<\/span><span class=\"token punctuation\">(<\/span>IOThread <span class=\"token operator\">*<\/span>t<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/ &#8230;<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>io_flags <span class=\"token operator\">&amp;<\/span> CLIENT_IO_PENDING_COMMAND<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/* [\u6838\u5fc3] \u6267\u884c\u547d\u4ee4&#xff0c;\u7ed3\u679c\u5199\u5165\u8f93\u51fa\u7f13\u51b2\u533a&#xff08;\u5185\u5b58&#xff09; *\/<\/span><br \/>\n        <span class=\"token function\">processPendingCommandAndInputBuffer<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token comment\">\/* \u6267\u884c\u5b8c\u6bd5&#xff0c;\u5c06 Client \u6254\u56de\u7ed9 IO \u7ebf\u7a0b *\/<\/span><br \/>\n    <span class=\"token function\">listLinkNodeHead<\/span><span class=\"token punctuation\">(<\/span>mainThreadPendingClientsToIOThreads<span class=\"token punctuation\">[<\/span>c<span class=\"token operator\">-&gt;<\/span>tid<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span> node<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>\u9636\u6bb5\u4e09&#xff1a;\u670d\u52a1\u5458\u4e0a\u83dc&#xff08;IO Thread Write&#xff09;<\/h4>\n<p>IO \u7ebf\u7a0b\u91cd\u65b0\u63a5\u7ba1 Client&#xff0c;\u53d1\u73b0\u8f93\u51fa\u7f13\u51b2\u533a\u6709\u6570\u636e&#xff0c;\u8c03\u7528 writeToClient \u5c06\u6570\u636e\u63a8\u5165\u7f51\u5361\u3002<\/p>\n<h3>5.4 \u7ebf\u7a0b\u540c\u6b65\u539f\u8bed&#xff1a;EventFD \u4e0e\u81ea\u9002\u5e94\u9501<\/h3>\n<p>\u5728\u5982\u6b64\u9ad8\u9891\u7684\u4ea4\u4e92\u4e2d&#xff0c;Redis 8.4 \u653e\u5f03\u4e86\u65e7\u7248\u672c\u4f4e\u6548\u7684 Busy Wait&#xff08;\u5fd9\u8f6e\u8be2&#xff09;&#xff0c;\u8f6c\u800c\u91c7\u7528\u66f4\u73b0\u4ee3\u7684\u540c\u6b65\u673a\u5236\u3002<\/p>\n<h4>1. \u5524\u9192\u673a\u5236&#xff1a;EventFD \u53d6\u4ee3 While(1)<\/h4>\n<p>\u65e7\u7248\u672c\u4e3b\u7ebf\u7a0b\u5728\u5206\u53d1\u4efb\u52a1\u540e\u4f1a\u6b7b\u5faa\u73af\u7a7a\u8f6c\u7b49\u5f85\u30028.4 \u7248\u672c\u4e2d&#xff0c;IO \u7ebf\u7a0b\u6ca1\u6709\u4efb\u52a1\u65f6\u4f1a\u901a\u8fc7 epoll_wait \u6302\u8d77&#xff08;Sleep&#xff09;&#xff0c;\u8282\u7701 CPU\u3002\u4e3b\u7ebf\u7a0b\u901a\u8fc7\u5199 EventFD&#xff08;\u6216 Pipe&#xff09;\u6765\u5524\u9192\u5b83\u3002<\/p>\n<p><span class=\"token comment\">\/* src\/iothread.c *\/<\/span><br \/>\n<span class=\"token keyword\">static<\/span> <span class=\"token keyword\">inline<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">sendPendingClientsToMainThreadIfNeeded<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/ \u4ec5\u5f53\u63a5\u6536\u65b9\u5904\u4e8e\u7761\u7720\u6216\u7a7a\u95f2\u72b6\u6001\u65f6&#xff0c;\u624d\u89e6\u53d1\u7cfb\u7edf\u8c03\u7528\u5524\u9192\u5b83<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>running <span class=\"token operator\">&amp;&amp;<\/span> <span class=\"token operator\">!<\/span>pending<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token function\">triggerEventNotifier<\/span><span class=\"token punctuation\">(<\/span>mainThreadPendingClientsNotifiers<span class=\"token punctuation\">[<\/span>t<span class=\"token operator\">-&gt;<\/span>id<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>2. \u9501\u7684\u7c92\u5ea6&#xff1a;pthread_mutex \u7684\u6279\u91cf\u64cd\u4f5c<\/h4>\n<p>\u867d\u7136\u5f15\u5165\u4e86\u9501&#xff0c;\u4f46\u9501\u7684\u7c92\u5ea6\u88ab\u8bbe\u8ba1\u5f97\u6781\u7c97\u2014\u2014\u53ea\u9501\u201c\u961f\u5217\u4ea4\u6362\u201d\u7684\u90a3\u4e00\u77ac\u95f4&#xff0c;\u800c\u4e0d\u662f\u9501\u6bcf\u4e2a\u8bf7\u6c42\u3002<\/p>\n<p><span class=\"token comment\">\/* \u6279\u91cf\u63a5\u6536\u793a\u4f8b *\/<\/span><br \/>\n<span class=\"token function\">pthread_mutex_lock<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>t<span class=\"token operator\">-&gt;<\/span>pending_clients_mutex<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token comment\">\/* O(1) \u64cd\u4f5c&#xff1a;\u77ac\u95f4\u5c06\u4e3b\u7ebf\u7a0b\u63a8\u8fc7\u6765\u7684\u6574\u4e2a\u94fe\u8868\u62fc\u63a5\u5230\u81ea\u5df1\u7684\u961f\u5217\u4e0a *\/<\/span><br \/>\n<span class=\"token function\">listJoin<\/span><span class=\"token punctuation\">(<\/span>t<span class=\"token operator\">-&gt;<\/span>pending_clients<span class=\"token punctuation\">,<\/span> mainThreadPendingClientsToIOThreads<span class=\"token punctuation\">[<\/span>i<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token function\">pthread_mutex_unlock<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>t<span class=\"token operator\">-&gt;<\/span>pending_clients_mutex<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>\u8fd9\u610f\u5473\u7740\u5904\u7406 1000 \u4e2a\u8bf7\u6c42\u53ef\u80fd\u53ea\u9700\u8981\u4e89\u62a2\u4e00\u6b21\u9501&#xff0c;\u5f00\u9500\u51e0\u4e4e\u53ef\u4ee5\u5ffd\u7565\u4e0d\u8ba1\u3002<\/p>\n<h4>3. \u5168\u5c40\u6682\u505c&#xff1a;pauseAllIOThreads<\/h4>\n<p>\u5f53\u4e3b\u7ebf\u7a0b\u9700\u8981\u8fdb\u884c Hash Resize \u6216\u914d\u7f6e\u70ed\u52a0\u8f7d\u65f6&#xff0c;\u9700\u8981\u786e\u4fdd\u4e16\u754c\u9759\u6b62\u3002Redis \u5b9e\u73b0\u4e86\u4e00\u4e2a\u57fa\u4e8e\u539f\u5b50\u53d8\u91cf\u7684\u201c\u7ea2\u7eff\u706f\u201d\u673a\u5236\u3002<\/p>\n<ul>\n<li>\u4e3b\u7ebf\u7a0b\u8bbe\u7f6e t-&gt;paused &#061; PAUSING\u3002<\/li>\n<li>IO \u7ebf\u7a0b\u5728\u4e0b\u4e00\u6b21\u5faa\u73af\u524d\u68c0\u67e5\u8be5\u53d8\u91cf&#xff0c;\u4e3b\u52a8\u8fdb\u5165\u6b7b\u5faa\u73af\u81ea\u65cb&#xff08;Spin&#xff09;\u6216\u4f11\u7720\u72b6\u6001&#xff0c;\u76f4\u5230\u4e3b\u7ebf\u7a0b\u89e3\u9664\u6682\u505c\u3002<\/li>\n<\/ul>\n<p><span class=\"token comment\">\/* IO \u7ebf\u7a0b\u7684\u81ea\u6211\u4fee\u517b *\/<\/span><br \/>\n<span class=\"token keyword\">void<\/span> <span class=\"token function\">handlePauseAndResume<\/span><span class=\"token punctuation\">(<\/span>IOThread <span class=\"token operator\">*<\/span>t<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> paused<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token function\">atomicGetWithSync<\/span><span class=\"token punctuation\">(<\/span>t<span class=\"token operator\">-&gt;<\/span>paused<span class=\"token punctuation\">,<\/span> paused<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>paused <span class=\"token operator\">&#061;&#061;<\/span> IO_THREAD_PAUSING<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u4e3b\u52a8\u6302\u8d77&#xff0c;\u7b49\u5f85\u4e3b\u7ebf\u7a0b\u4fe1\u53f7<\/span><br \/>\n        <span class=\"token keyword\">while<\/span> <span class=\"token punctuation\">(<\/span>paused <span class=\"token operator\">!&#061;<\/span> IO_THREAD_RESUMING<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token function\">atomicGetWithSync<\/span><span class=\"token punctuation\">(<\/span>t<span class=\"token operator\">-&gt;<\/span>paused<span class=\"token punctuation\">,<\/span> paused<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>      IO\u7ebf\u7a0b(Waiter) <\/p>\n<p>      \u4ea4\u6362\u961f\u5217 <\/p>\n<p>      \u4e3b\u7ebf\u7a0b(Chef) <\/p>\n<p>      \u5ba2\u6237\u7aef <\/p>\n<p>       IO\u7ebf\u7a0b(Waiter) <\/p>\n<p>       \u4ea4\u6362\u961f\u5217 <\/p>\n<p>       \u4e3b\u7ebf\u7a0b(Chef) <\/p>\n<p>       \u5ba2\u6237\u7aef <\/p>\n<p>  #mermaid-svg-IAb2vTYFJ5PbCW1d{font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-IAb2vTYFJ5PbCW1d .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-IAb2vTYFJ5PbCW1d .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-IAb2vTYFJ5PbCW1d .error-icon{fill:#552222;}#mermaid-svg-IAb2vTYFJ5PbCW1d .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-IAb2vTYFJ5PbCW1d .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-IAb2vTYFJ5PbCW1d .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-IAb2vTYFJ5PbCW1d .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-IAb2vTYFJ5PbCW1d .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-IAb2vTYFJ5PbCW1d .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-IAb2vTYFJ5PbCW1d .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-IAb2vTYFJ5PbCW1d .marker{fill:#333333;stroke:#333333;}#mermaid-svg-IAb2vTYFJ5PbCW1d .marker.cross{stroke:#333333;}#mermaid-svg-IAb2vTYFJ5PbCW1d svg{font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-IAb2vTYFJ5PbCW1d p{margin:0;}#mermaid-svg-IAb2vTYFJ5PbCW1d .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-IAb2vTYFJ5PbCW1d text.actor&gt;tspan{fill:black;stroke:none;}#mermaid-svg-IAb2vTYFJ5PbCW1d .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-IAb2vTYFJ5PbCW1d .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-IAb2vTYFJ5PbCW1d .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-IAb2vTYFJ5PbCW1d .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-IAb2vTYFJ5PbCW1d #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-IAb2vTYFJ5PbCW1d .sequenceNumber{fill:white;}#mermaid-svg-IAb2vTYFJ5PbCW1d #sequencenumber{fill:#333;}#mermaid-svg-IAb2vTYFJ5PbCW1d #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-IAb2vTYFJ5PbCW1d .messageText{fill:#333;stroke:none;}#mermaid-svg-IAb2vTYFJ5PbCW1d .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-IAb2vTYFJ5PbCW1d .labelText,#mermaid-svg-IAb2vTYFJ5PbCW1d .labelText&gt;tspan{fill:black;stroke:none;}#mermaid-svg-IAb2vTYFJ5PbCW1d .loopText,#mermaid-svg-IAb2vTYFJ5PbCW1d .loopText&gt;tspan{fill:black;stroke:none;}#mermaid-svg-IAb2vTYFJ5PbCW1d .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-IAb2vTYFJ5PbCW1d .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-IAb2vTYFJ5PbCW1d .noteText,#mermaid-svg-IAb2vTYFJ5PbCW1d .noteText&gt;tspan{fill:black;stroke:none;}#mermaid-svg-IAb2vTYFJ5PbCW1d .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-IAb2vTYFJ5PbCW1d .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-IAb2vTYFJ5PbCW1d .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-IAb2vTYFJ5PbCW1d .actorPopupMenu{position:absolute;}#mermaid-svg-IAb2vTYFJ5PbCW1d .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 \/ 0.4));}#mermaid-svg-IAb2vTYFJ5PbCW1d .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-IAb2vTYFJ5PbCW1d .actor-man circle,#mermaid-svg-IAb2vTYFJ5PbCW1d line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-IAb2vTYFJ5PbCW1d :root{&#8211;mermaid-font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;} <\/p>\n<p>      \u9636\u6bb5\u4e00&#xff1a;\u8fde\u63a5\u5378\u8f7d (Connection Offloading) <\/p>\n<p>      \u9636\u6bb5\u4e8c&#xff1a;\u547d\u4ee4\u8bfb\u53d6\u4e0e\u89e3\u6790 <\/p>\n<p>      \u9636\u6bb5\u4e09&#xff1a;\u4e3b\u7ebf\u7a0b\u6267\u884c <\/p>\n<p>      \u6301\u6709 Client \u5b8c\u5168\u63a7\u5236\u6743 <\/p>\n<p>      \u9636\u6bb5\u56db&#xff1a;\u54cd\u5e94\u56de\u5199 <\/p>\n<p>    1. \u53d1\u8d77 TCP \u8fde\u63a5 <\/p>\n<p>    1 <\/p>\n<p>    accept() \u83b7\u53d6 fd <\/p>\n<p>    2 <\/p>\n<p>    epoll_ctl(DEL) \u89e3\u7ed1 <\/p>\n<p>    3 <\/p>\n<p>    2. Client \u6307\u9488\u5165\u961f <\/p>\n<p>    4 <\/p>\n<p>    3. \u5199 EventFD \u5524\u9192 IO \u7ebf\u7a0b <\/p>\n<p>    5 <\/p>\n<p>    \u53d6\u51fa Client <\/p>\n<p>    6 <\/p>\n<p>    epoll_ctl(ADD) \u7ed1\u5b9aIO\u7ebf\u7a0b <\/p>\n<p>    7 <\/p>\n<p>    4. \u53d1\u9001\u547d\u4ee4 (SET k v) <\/p>\n<p>    8 <\/p>\n<p>    readQueryFromClient <\/p>\n<p>    9 <\/p>\n<p>    \u534f\u8bae\u89e3\u6790 <\/p>\n<p>    10 <\/p>\n<p>    5. \u6807\u8bb0 Pending Command \u5165\u961f <\/p>\n<p>    11 <\/p>\n<p>    6. \u5199 EventFD \u5524\u9192\u4e3b\u7ebf\u7a0b <\/p>\n<p>    12 <\/p>\n<p>    \u53d6\u51fa Client <\/p>\n<p>    13 <\/p>\n<p>    processPendingCommand <\/p>\n<p>    14 <\/p>\n<p>    \u64cd\u4f5c DB \/ \u5199 AOF <\/p>\n<p>    15 <\/p>\n<p>    \u7ed3\u679c\u5199\u5165\u5185\u5b58\u7f13\u51b2\u533a <\/p>\n<p>    16 <\/p>\n<p>    7. Client \u56de\u6536\u5e76\u5165\u961f <\/p>\n<p>    17 <\/p>\n<p>    8. \u5199 EventFD \u5524\u9192 IO \u7ebf\u7a0b <\/p>\n<p>    18 <\/p>\n<p>    \u53d6\u51fa Client <\/p>\n<p>    19 <\/p>\n<p>    writeToClient <\/p>\n<p>    20 <\/p>\n<p>    9. \u8fd4\u56de\u7ed3\u679c OK <\/p>\n<p>    21 <\/p>\n<h2>\u7b2c\u516d\u90e8\u5206&#xff1a;\u547d\u4ee4\u6267\u884c\u4e0e\u56de\u590d\u7f13\u51b2\u533a&#xff08;Output Buffer&#xff09;\u7ba1\u7406<\/h2>\n<p>\u5f53 IO \u7ebf\u7a0b\u5c06 Socket \u4e2d\u7684\u6570\u636e\u8bfb\u53d6\u5e76\u89e3\u6790\u5b8c\u6bd5\u540e&#xff0c;client \u5bf9\u8c61\u88ab\u79fb\u4ea4\u7ed9\u4e3b\u7ebf\u7a0b\u3002\u6b64\u65f6&#xff0c;Redis \u8fdb\u5165\u4e86\u8ba1\u7b97\u5bc6\u96c6\u578b\u9636\u6bb5\u3002\u547d\u4ee4\u7684\u6267\u884c\u7ed3\u679c&#xff08;Reply&#xff09;\u5e76\u4e0d\u4f1a\u7acb\u5373\u89e6\u53d1\u7cfb\u7edf\u8c03\u7528\u5199\u5165 Socket&#xff0c;\u800c\u662f\u5148\u6682\u5b58\u5728\u7528\u6237\u6001\u7684\u8f93\u51fa\u7f13\u51b2\u533a&#xff08;Output Buffer&#xff09;\u4e2d&#xff0c;\u7b49\u5f85\u7edf\u4e00\u8c03\u5ea6\u3002<\/p>\n<h3>6.1 \u547d\u4ee4\u6267\u884c\u7684\u6838\u5fc3\u5165\u53e3&#xff1a;call() \u51fd\u6570\u5206\u6790<\/h3>\n<p>\u5728 src\/server.c \u4e2d&#xff0c;call() \u51fd\u6570\u662f\u547d\u4ee4\u6267\u884c\u7684\u201c\u603b\u5bfc\u6f14\u201d\u3002\u5b83\u4e0d\u4ec5\u8d1f\u8d23\u8c03\u7528\u5177\u4f53\u7684\u547d\u4ee4\u5b9e\u73b0&#xff0c;\u8fd8\u5904\u7406\u4e86 Slowlog \u8bb0\u5f55\u3001AOF \u4f20\u64ad\u3001\u76d1\u63a7&#xff08;Monitor&#xff09;\u63a8\u9001\u7b49\u526f\u4f5c\u7528\u3002<\/p>\n<p>\u6838\u5fc3\u6d41\u7a0b&#xff1a;<\/p>\n<li>\u67e5\u627e\u547d\u4ee4&#xff1a;\u5728 processCommand \u4e2d&#xff0c;\u901a\u8fc7 lookupCommand \u627e\u5230\u5bf9\u5e94\u7684 redisCommand \u7ed3\u6784\u4f53&#xff08;\u5982 setCommand&#xff09;\u3002<\/li>\n<li>\u591a\u6001\u8c03\u7528&#xff1a;call() \u51fd\u6570\u901a\u8fc7\u51fd\u6570\u6307\u9488\u6267\u884c\u5177\u4f53\u903b\u8f91&#xff1a;<span class=\"token comment\">\/* src\/server.c *\/<\/span><br \/>\nc<span class=\"token operator\">-&gt;<\/span>cmd<span class=\"token operator\">-&gt;<\/span><span class=\"token function\">proc<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n <\/li>\n<li>\u539f\u5b50\u6027\u4e0a\u4e0b\u6587&#xff1a;\u5728 call() \u6267\u884c\u671f\u95f4&#xff0c;\u4e3b\u7ebf\u7a0b\u88ab\u5f53\u524d Client \u72ec\u5360\u3002\u8fd9\u610f\u5473\u7740\u547d\u4ee4\u6267\u884c\u662f\u4e32\u884c\u7684\u3001\u539f\u5b50\u7684&#xff0c;\u4e0d\u4f1a\u53d1\u751f\u5e76\u53d1\u6570\u636e\u7ade\u4e89&#xff08;Race Condition&#xff09;\u3002<\/li>\n<li>\u6570\u636e\u751f\u4ea7&#xff1a;\u5177\u4f53\u7684\u547d\u4ee4\u51fd\u6570&#xff08;\u5982 getCommand&#xff09;\u4ece\u6570\u636e\u5e93\u67e5\u627e\u5230\u6570\u636e\u540e&#xff0c;\u5fc5\u987b\u8c03\u7528 addReply \u7cfb\u5217\u51fd\u6570\u3002\u8fd9\u662f\u6570\u636e\u4ece\u201c\u6570\u636e\u5e93\u5c42\u201d\u6d41\u5411\u201c\u7f51\u7edc\u5c42\u201d\u7684\u552f\u4e00\u5165\u53e3\u3002<\/li>\n<h3>6.2 \u56de\u590d\u6570\u636e\u7684\u5199\u5165\u94fe\u8def&#xff1a;addReply \u7cfb\u5217\u51fd\u6570<\/h3>\n<p>\u5728 src\/networking.c \u4e2d&#xff0c;addReply \u53ca\u5176\u53d8\u4f53&#xff08;addReplySds, addReplyBulk \u7b49&#xff09;\u8d1f\u8d23\u5c06\u6570\u636e\u5199\u5165 client \u7ed3\u6784\u4f53\u5185\u7684\u7f13\u51b2\u533a\u3002<\/p>\n<p>\u5173\u952e\u6e90\u7801\u903b\u8f91 (src\/networking.c)&#xff1a;<\/p>\n<li>\n<p>\u51c6\u5907\u9636\u6bb5 (_prepareClientToWrite)&#xff1a; \u6bcf\u6b21\u5199\u5165\u524d&#xff0c;Redis \u90fd\u4f1a\u68c0\u67e5 Client \u72b6\u6001\u3002<\/p>\n<ul>\n<li>\u5982\u679c Client \u662f Lua \u4f2a\u5ba2\u6237\u7aef\u6216 Module \u4f2a\u5ba2\u6237\u7aef&#xff0c;\u76f4\u63a5\u8fd4\u56de\u3002<\/li>\n<li>\u6838\u5fc3\u52a8\u4f5c&#xff1a;\u5982\u679c\u5f53\u524d Client \u8fd8\u6ca1\u6709\u88ab\u6807\u8bb0\u4e3a\u201c\u5f85\u5199\u201d&#xff0c;\u8c03\u7528 putClientInPendingWriteQueue(c)\u3002<\/li>\n<li>\u5165\u961f\u4e0d\u5199&#xff1a;\u8be5\u51fd\u6570\u4ec5\u5c06 Client \u6302\u5165\u5168\u5c40\u94fe\u8868 server.clients_pending_write&#xff0c;\u5e76\u6807\u8bb0 CLIENT_PENDING_WRITE\u3002\u6b64\u65f6\u7edd\u4e0d\u4f1a\u89e6\u53d1 write \u7cfb\u7edf\u8c03\u7528\u3002<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u6570\u636e\u8def\u7531 (_addReplyToBufferOrList)&#xff1a; \u6570\u636e\u5199\u5165\u54ea\u91cc&#xff1f;Redis \u91c7\u7528\u4e86\u53cc\u5c42\u7f13\u51b2\u7b56\u7565&#xff0c;\u8be5\u51fd\u6570\u8d1f\u8d23\u8def\u7531\u51b3\u7b56\u3002<\/p>\n<\/li>\n<h3>6.3 \u9759\u6001\u7f13\u51b2\u533a buf \u4e0e\u52a8\u6001\u94fe\u8868 reply \u7684\u5207\u6362\u903b\u8f91<\/h3>\n<p>\u4e3a\u4e86\u5728\u201c\u5c0f\u6570\u636e\u9ad8\u6027\u80fd\u201d\u548c\u201c\u5927\u6570\u636e\u5927\u5bb9\u91cf\u201d\u4e4b\u95f4\u53d6\u5f97\u5e73\u8861&#xff0c;Redis 8.4 \u8bbe\u8ba1\u4e86\u4e24\u7ea7\u7f13\u51b2\u673a\u5236\u3002<\/p>\n<h4>\u7b2c\u4e00\u7ea7&#xff1a;\u9759\u6001\u56fa\u5b9a\u7f13\u51b2\u533a (c-&gt;buf)<\/h4>\n<ul>\n<li>\u5b9a\u4e49&#xff1a;client \u7ed3\u6784\u4f53\u4e2d\u5185\u5d4c\u7684\u4e00\u4e2a 16KB \u5b57\u8282\u6570\u7ec4&#xff08;PROTO_REPLY_CHUNK_BYTES&#xff09;\u3002<\/li>\n<li>\u4f18\u52bf&#xff1a;\u96f6\u5206\u914d&#xff08;Zero-Allocation&#xff09;\u3002\u5b83\u968f client \u7ed3\u6784\u4f53\u4e00\u540c\u5206\u914d&#xff0c;\u4e0d\u9700\u8981\u989d\u5916\u7684 malloc&#xff0c;\u4e14 CPU \u7f13\u5b58\u4eb2\u548c\u6027\u6781\u9ad8\u3002<\/li>\n<li>\u7b56\u7565&#xff1a;\u53ea\u8981\u94fe\u8868\u4e3a\u7a7a\u4e14 buf \u8fd8\u6709\u7a7a\u95f4&#xff0c;\u4f18\u5148\u5199\u5165\u8fd9\u91cc\u3002<\/li>\n<\/ul>\n<h4>\u7b2c\u4e8c\u7ea7&#xff1a;\u52a8\u6001\u54cd\u5e94\u94fe\u8868 (c-&gt;reply)<\/h4>\n<ul>\n<li>\u5b9a\u4e49&#xff1a;\u4e00\u4e2a\u53cc\u5411\u94fe\u8868&#xff0c;\u8282\u70b9\u627f\u8f7d\u5177\u4f53\u7684\u54cd\u5e94\u6570\u636e\u5757\u3002<\/li>\n<li>\u4f18\u52bf&#xff1a;\u5bb9\u91cf\u65e0\u4e0a\u9650&#xff08;\u53d7 maxmemory \u9650\u5236&#xff09;\u3002<\/li>\n<li>\u7b56\u7565&#xff1a;\n<ul>\n<li>\u5f53 c-&gt;buf \u6ee1\u6ea2\u65f6&#xff0c;\u542f\u7528\u94fe\u8868\u3002<\/li>\n<li>\u4e3a\u4fdd\u6301 FIFO \u987a\u5e8f&#xff0c;\u4e00\u65e6\u4f7f\u7528\u4e86\u94fe\u8868&#xff0c;\u540e\u7eed\u6240\u6709\u6570\u636e\u5f3a\u5236\u8ffd\u52a0\u5230\u94fe\u8868\u5c3e\u90e8\u3002<\/li>\n<\/ul>\n<\/li>\n<li>\u5185\u5b58\u4f18\u5316&#xff1a;trimReplyUnusedTailSpace \u51fd\u6570\u4f1a\u76d1\u63a7\u94fe\u8868\u5c3e\u90e8\u8282\u70b9\u7684\u5229\u7528\u7387\u3002\u5982\u679c\u5c3e\u8282\u70b9\u5206\u914d\u4e86\u5f88\u5927\u7a7a\u95f4\u4f46\u53ea\u7528\u4e86\u5f88\u5c11&#xff0c;Redis \u4f1a\u901a\u8fc7 realloc \u7f29\u5bb9&#xff0c;\u51cf\u5c11\u5185\u5b58\u788e\u7247\u3002<\/li>\n<\/ul>\n<h3>6.4 \u5ef6\u8fdf\u5199\u56de\u4e0e\u591a\u7ebf\u7a0b\u5206\u53d1&#xff1a;handleClientsWithPendingWrites \u7684\u8def\u7531\u673a\u5236<\/h3>\n<p>\u8fd9\u662f Redis 8.4 \u7f51\u7edc\u6a21\u578b\u4e2d\u6700\u5173\u952e\u7684\u5206\u53d1\u5668&#xff08;Router&#xff09;\u3002<\/p>\n<p>\u5728 beforeSleep \u9636\u6bb5&#xff0c;\u4e3b\u7ebf\u7a0b\u9700\u8981\u5904\u7406 server.clients_pending_write \u94fe\u8868\u4e2d\u7684\u6240\u6709\u5ba2\u6237\u7aef\u3002\u6b64\u65f6&#xff0c;\u56de\u590d\u6570\u636e\u5df2\u7ecf\u8eba\u5728\u5185\u5b58\u7f13\u51b2\u533a\u91cc\u4e86&#xff0c;\u63a5\u4e0b\u6765\u7684\u95ee\u9898\u662f&#xff1a;\u8c01\u8d1f\u8d23\u628a\u5b83\u4eec\u53d1\u7ed9\u7f51\u5361&#xff1f;<\/p>\n<p>\u6e90\u7801\u6df1\u5ea6\u89e3\u6790 (src\/networking.c):<\/p>\n<p><span class=\"token keyword\">int<\/span> <span class=\"token function\">handleClientsWithPendingWrites<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">void<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    listIter li<span class=\"token punctuation\">;<\/span><br \/>\n    listNode <span class=\"token operator\">*<\/span>ln<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token comment\">\/\/ &#8230; \u904d\u5386\u5f85\u5199\u94fe\u8868 &#8230;<\/span><br \/>\n    <span class=\"token keyword\">while<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>ln <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">listNext<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>li<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        client <span class=\"token operator\">*<\/span>c <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">listNodeValue<\/span><span class=\"token punctuation\">(<\/span>ln<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        c<span class=\"token operator\">-&gt;<\/span>flags <span class=\"token operator\">&amp;&#061;<\/span> <span class=\"token operator\">~<\/span>CLIENT_PENDING_WRITE<span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u6e05\u9664\u6807\u8bb0<\/span><\/p>\n<p>        <span class=\"token comment\">\/* [\u6838\u5fc3\u8def\u7531] \u5224\u65ad\u662f\u5426\u5f00\u542f\u4e86\u591a\u7ebf\u7a0b IO *\/<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>server<span class=\"token punctuation\">.<\/span>io_threads_num <span class=\"token operator\">&gt;<\/span> <span class=\"token number\">1<\/span> <span class=\"token operator\">&amp;&amp;<\/span><br \/>\n            <span class=\"token operator\">!<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>flags <span class=\"token operator\">&amp;<\/span> CLIENT_CLOSE_AFTER_REPLY<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&amp;&amp;<\/span><br \/>\n            <span class=\"token operator\">!<\/span><span class=\"token function\">isClientMustHandledByMainThread<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token comment\">\/* \u8def\u5f84 A&#xff1a;\u79fb\u4ea4\u7ed9 IO \u7ebf\u7a0b (Offloading) *\/<\/span><br \/>\n            <span class=\"token comment\">\/* \u4e3b\u7ebf\u7a0b\u4ec5\u4ec5\u662f\u5c06 Client \u6307\u9488\u201c\u8fc7\u6237\u201d\u7ed9 IO \u7ebf\u7a0b&#xff0c;\u4e0d\u6267\u884c syscall *\/<\/span><br \/>\n            <span class=\"token function\">assignClientToIOThread<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">continue<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/* \u8def\u5f84 B&#xff1a;\u4e3b\u7ebf\u7a0b\u515c\u5e95 (Fallback) *\/<\/span><br \/>\n        <span class=\"token comment\">\/* \u4ec5\u5728\u591a\u7ebf\u7a0b\u672a\u5f00\u542f&#xff0c;\u6216 Client \u72b6\u6001\u7279\u6b8a&#xff08;\u5982\u9700\u7acb\u5373\u5173\u95ed&#xff09;\u65f6\u6267\u884c *\/<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token function\">writeToClient<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">,<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> C_ERR<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">continue<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/* \u5982\u679c\u4e00\u6b21\u6ca1\u5199\u5b8c&#xff0c;\u624d\u6ce8\u518c epoll \u5199\u4e8b\u4ef6 *\/<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token function\">clientHasPendingReplies<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token function\">installClientWriteHandler<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> processed<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>\u8def\u5f84 A&#xff1a;IO \u7ebf\u7a0b\u6d88\u8d39&#xff08;\u9ad8\u6027\u80fd\u4e3b\u8def\u5f84&#xff09;<\/h4>\n<p>\u8fd9\u662f Redis 8.4 \u541e\u5410\u91cf\u98d9\u5347\u7684\u79d8\u8bc0\u3002<\/p>\n<li>\u79fb\u4ea4&#xff1a;\u4e3b\u7ebf\u7a0b\u8c03\u7528 assignClientToIOThread&#xff0c;\u5c06 Client \u653e\u5165 IO \u7ebf\u7a0b\u7684\u961f\u5217&#xff0c;\u5e76\u5524\u9192 IO \u7ebf\u7a0b\u3002<\/li>\n<li>\u5e76\u53d1\u5199&#xff1a;IO \u7ebf\u7a0b\u5728 processClientsFromMainThread \u4e2d\u63a5\u7ba1 Client&#xff0c;\u8c03\u7528 writeToClient\u3002<\/li>\n<li>\u7cfb\u7edf\u8c03\u7528&#xff1a;writev \u7cfb\u7edf\u8c03\u7528\u5728 Worker \u7ebf\u7a0b\u4e2d\u5e76\u53d1\u6267\u884c\u3002\u8fd9\u610f\u5473\u7740\u5982\u679c\u5e26\u5bbd\u6253\u6ee1&#xff0c;\u963b\u585e\u7684\u662f Worker \u7ebf\u7a0b&#xff0c;\u4e3b\u7ebf\u7a0b\u4f9d\u7136\u53ef\u4ee5\u5904\u7406\u5176\u4ed6\u903b\u8f91\u3002<\/li>\n<h4>\u8def\u5f84 B&#xff1a;\u4e3b\u7ebf\u7a0b\u515c\u5e95<\/h4>\n<p>\u5f53 server.io_threads_num &#061;&#061; 1 \u6216\u9047\u5230\u7279\u6b8a Client&#xff08;\u5982 Debug \u5ba2\u6237\u7aef\u3001\u7acb\u5373\u5173\u95ed\u7684\u8fde\u63a5&#xff09;\u65f6&#xff0c;\u4e3b\u7ebf\u7a0b\u4f1a\u4eb2\u81ea\u8c03\u7528 writeToClient\u3002<\/p>\n<h4>\u603b\u7ed3&#xff1a;\u751f\u4ea7\u8005-\u6d88\u8d39\u8005\u6a21\u578b<\/h4>\n<p>Redis 8.4 \u7684\u8f93\u51fa\u7ba1\u7406\u5b8c\u7f8e\u8be0\u91ca\u4e86\u65e0\u9501&#xff08;\u6216\u4f4e\u9501&#xff09;\u534f\u4f5c&#xff1a;<\/p>\n<ul>\n<li>\u4e3b\u7ebf\u7a0b&#xff08;\u751f\u4ea7\u8005&#xff09;&#xff1a;\u8d1f\u8d23\u8ba1\u7b97&#xff0c;\u4ea7\u51fa\u6570\u636e\u5230 c-&gt;buf\/reply\u3002\u64cd\u4f5c\u7eaf\u5185\u5b58&#xff0c;\u6781\u5feb\u3002<\/li>\n<li>IO \u7ebf\u7a0b&#xff08;\u6d88\u8d39\u8005&#xff09;&#xff1a;\u8d1f\u8d23 IO&#xff0c;\u5c06 c-&gt;buf\/reply \u7684\u6570\u636e\u51b2\u5237\u5230 Socket\u3002\u64cd\u4f5c fd&#xff0c;\u627f\u62c5\u7cfb\u7edf\u8c03\u7528\u5f00\u9500\u3002<\/li>\n<\/ul>\n<p>  #mermaid-svg-4fXpT3qUQUueAsWZ{font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-4fXpT3qUQUueAsWZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-4fXpT3qUQUueAsWZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-4fXpT3qUQUueAsWZ .error-icon{fill:#552222;}#mermaid-svg-4fXpT3qUQUueAsWZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4fXpT3qUQUueAsWZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-4fXpT3qUQUueAsWZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4fXpT3qUQUueAsWZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4fXpT3qUQUueAsWZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-4fXpT3qUQUueAsWZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4fXpT3qUQUueAsWZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4fXpT3qUQUueAsWZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4fXpT3qUQUueAsWZ .marker.cross{stroke:#333333;}#mermaid-svg-4fXpT3qUQUueAsWZ svg{font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4fXpT3qUQUueAsWZ p{margin:0;}#mermaid-svg-4fXpT3qUQUueAsWZ .label{font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;color:#333;}#mermaid-svg-4fXpT3qUQUueAsWZ .cluster-label text{fill:#333;}#mermaid-svg-4fXpT3qUQUueAsWZ .cluster-label span{color:#333;}#mermaid-svg-4fXpT3qUQUueAsWZ .cluster-label span p{background-color:transparent;}#mermaid-svg-4fXpT3qUQUueAsWZ .label text,#mermaid-svg-4fXpT3qUQUueAsWZ span{fill:#333;color:#333;}#mermaid-svg-4fXpT3qUQUueAsWZ .node rect,#mermaid-svg-4fXpT3qUQUueAsWZ .node circle,#mermaid-svg-4fXpT3qUQUueAsWZ .node ellipse,#mermaid-svg-4fXpT3qUQUueAsWZ .node polygon,#mermaid-svg-4fXpT3qUQUueAsWZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-4fXpT3qUQUueAsWZ .rough-node .label text,#mermaid-svg-4fXpT3qUQUueAsWZ .node .label text,#mermaid-svg-4fXpT3qUQUueAsWZ .image-shape .label,#mermaid-svg-4fXpT3qUQUueAsWZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-4fXpT3qUQUueAsWZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-4fXpT3qUQUueAsWZ .rough-node .label,#mermaid-svg-4fXpT3qUQUueAsWZ .node .label,#mermaid-svg-4fXpT3qUQUueAsWZ .image-shape .label,#mermaid-svg-4fXpT3qUQUueAsWZ .icon-shape .label{text-align:center;}#mermaid-svg-4fXpT3qUQUueAsWZ .node.clickable{cursor:pointer;}#mermaid-svg-4fXpT3qUQUueAsWZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-4fXpT3qUQUueAsWZ .arrowheadPath{fill:#333333;}#mermaid-svg-4fXpT3qUQUueAsWZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-4fXpT3qUQUueAsWZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-4fXpT3qUQUueAsWZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4fXpT3qUQUueAsWZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-4fXpT3qUQUueAsWZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4fXpT3qUQUueAsWZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-4fXpT3qUQUueAsWZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-4fXpT3qUQUueAsWZ .cluster text{fill:#333;}#mermaid-svg-4fXpT3qUQUueAsWZ .cluster span{color:#333;}#mermaid-svg-4fXpT3qUQUueAsWZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-4fXpT3qUQUueAsWZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-4fXpT3qUQUueAsWZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-4fXpT3qUQUueAsWZ .icon-shape,#mermaid-svg-4fXpT3qUQUueAsWZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4fXpT3qUQUueAsWZ .icon-shape p,#mermaid-svg-4fXpT3qUQUueAsWZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-4fXpT3qUQUueAsWZ .icon-shape rect,#mermaid-svg-4fXpT3qUQUueAsWZ .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4fXpT3qUQUueAsWZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-4fXpT3qUQUueAsWZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-4fXpT3qUQUueAsWZ :root{&#8211;mermaid-font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;}#mermaid-svg-4fXpT3qUQUueAsWZ .mainThread&gt;*{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;}#mermaid-svg-4fXpT3qUQUueAsWZ .mainThread span{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;}#mermaid-svg-4fXpT3qUQUueAsWZ .ioThread&gt;*{fill:#fff3e0!important;stroke:#e65100!important;stroke-width:2px!important;}#mermaid-svg-4fXpT3qUQUueAsWZ .ioThread span{fill:#fff3e0!important;stroke:#e65100!important;stroke-width:2px!important;}#mermaid-svg-4fXpT3qUQUueAsWZ .buffer&gt;*{fill:#e8f5e9!important;stroke:#2e7d32!important;stroke-width:2px!important;stroke-dasharray:5 5!important;}#mermaid-svg-4fXpT3qUQUueAsWZ .buffer span{fill:#e8f5e9!important;stroke:#2e7d32!important;stroke-width:2px!important;stroke-dasharray:5 5!important;}#mermaid-svg-4fXpT3qUQUueAsWZ .decision&gt;*{fill:#fff9c4!important;stroke:#fbc02d!important;stroke-width:2px!important;}#mermaid-svg-4fXpT3qUQUueAsWZ .decision span{fill:#fff9c4!important;stroke:#fbc02d!important;stroke-width:2px!important;} <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>\u8def\u5f84 B: \u515c\u5e95 (Main Thread)<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>\u8def\u5f84 A: \u6d88\u8d39\u8005 (IO Thread)<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>\u9636\u6bb5\u4e8c&#xff1a;\u8def\u7531\u5206\u53d1 (Router)<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>\u9636\u6bb5\u4e00&#xff1a;\u751f\u4ea7\u8005 (Main Thread)<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/p>\n<p>\u94fe\u8868\u4e3a\u7a7a &amp; buf\u6709\u7a7a\u95f4<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/p>\n<p>buf\u5df2\u6ee1 \u6216 \u94fe\u8868\u975e\u7a7a<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/p>\n<p>\u8fdb\u5165 beforeSleep<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/p>\n<p>Yes (\u9ad8\u6027\u80fd\u8def\u5f84)<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/p>\n<p>No (\u515c\u5e95\u8def\u5f84)<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/span> <\/p>\n<p>         <span class=\"edgeLabel\"><\/p>\n<p>Yes<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>call \u547d\u4ee4\u6267\u884c\u5165\u53e3<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>c-&gt;cmd-&gt;proc \u6267\u884c\u4e1a\u52a1\u903b\u8f91<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>\u8c03\u7528 addReply<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>\u7f13\u51b2\u533a\u7b56\u7565\u5224\u5b9a<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>\u5199\u5165 c-&gt;buf (16KB \u9759\u6001\u6570\u7ec4)<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>\u8ffd\u52a0\u5230 c-&gt;reply (\u52a8\u6001\u53cc\u5411\u94fe\u8868)<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>\u6807\u8bb0 PENDING_WRITE\u52a0\u5165 clients_pending_write<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>handleClientsWithPendingWrites<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>\u8def\u7531\u5224\u65ad:1. io_threads &gt; 1 ?2. \u9002\u5408\u5378\u8f7d ?<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>assignClientToIOThread (\u8fde\u63a5\u8fc7\u6237)<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>\u5524\u9192 IO \u7ebf\u7a0b<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>IO\u7ebf\u7a0b\u5904\u7406<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>Syscall: writev (\u5e76\u53d1\u5199 Socket)<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>\u4e3b\u7ebf\u7a0b: writeToClient<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>Syscall: writev (\u540c\u6b65\u5199 Socket)<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>\u6ca1\u5199\u5b8c?<\/p>\n<p><\/span> <\/p>\n<p>         <span class=\"nodeLabel\"><\/p>\n<p>\u6ce8\u518c AE_WRITABLE \u4e8b\u4ef6<\/p>\n<p><\/span> <\/p>\n<p>\u8fd9\u662f\u57fa\u4e8e Redis 8.4 \u6e90\u7801&#xff08;src\/networking.c&#xff09;\u91cd\u6784\u540e\u7684\u7b2c\u4e03\u90e8\u5206\u3002<\/p>\n<p>\u5728\u4e0a\u4e00\u90e8\u5206&#xff0c;\u6211\u4eec\u89e3\u51b3\u4e86\u201c\u7531\u8c01\u6765\u5199&#xff08;\u4e3b\u7ebf\u7a0b vs IO \u7ebf\u7a0b&#xff09;\u201d\u7684\u8def\u7531\u95ee\u9898\u3002\u8fd9\u4e00\u90e8\u5206\u6211\u4eec\u5c06\u6df1\u5165\u5230\u5e95\u5c42&#xff0c;\u63a2\u7a76\u201c\u6570\u636e\u662f\u5982\u4f55\u88ab\u5199\u5165 Socket \u7684\u201d&#xff0c;\u4ee5\u53ca\u201c\u5f53\u6570\u636e\u5199\u4e0d\u5b8c\u6216\u79ef\u538b\u592a\u591a\u65f6&#xff0c;Redis \u5982\u4f55\u81ea\u6211\u4fdd\u62a4\u201d\u3002<\/p>\n<p>\u8fd9\u91cc\u5c55\u793a\u4e86 Redis \u5728\u7cfb\u7edf\u8c03\u7528\u5c42\u9762\u7684\u6781\u81f4\u4f18\u5316&#xff08;Scatter-Gather IO&#xff09;\u548c\u5728\u5185\u5b58\u7ba1\u7406\u5c42\u9762\u7684\u9632\u5fa1\u673a\u5236\u3002<\/p>\n<hr \/>\n<h2>\u7b2c\u4e03\u90e8\u5206&#xff1a;\u5e95\u5c42 IO \u5b9e\u73b0\u4e0e\u7f13\u51b2\u533a\u6ea2\u51fa\u4fdd\u62a4<\/h2>\n<h3>7.1 \u7cfb\u7edf\u8c03\u7528\u4f18\u5316&#xff1a;_writevToClient \u7684\u805a\u96c6\u5199&#xff08;Scatter-Gather I\/O&#xff09;\u5b9e\u73b0<\/h3>\n<p>Redis \u7684\u8f93\u51fa\u7f13\u51b2\u533a\u7531\u4e24\u90e8\u5206\u7ec4\u6210&#xff1a;\u4e00\u6bb5\u8fde\u7eed\u7684\u9759\u6001\u5185\u5b58&#xff08;c-&gt;buf&#xff09;\u548c\u4e00\u4e2a\u975e\u8fde\u7eed\u7684\u94fe\u8868&#xff08;c-&gt;reply&#xff09;\u3002\u5982\u679c\u4f7f\u7528\u666e\u901a\u7684 write \u7cfb\u7edf\u8c03\u7528&#xff0c;Redis \u9700\u8981\u5148\u53d1\u9001\u9759\u6001\u7f13\u51b2&#xff0c;\u518d\u904d\u5386\u94fe\u8868\u9010\u4e2a\u53d1\u9001\u8282\u70b9&#xff0c;\u8fd9\u5c06\u5bfc\u81f4\u591a\u6b21\u7528\u6237\u6001\/\u5185\u6838\u6001\u5207\u6362\u3002<\/p>\n<p>Redis 8.4 \u4f7f\u7528 writev \u7cfb\u7edf\u8c03\u7528\u6765\u5b9e\u73b0 \u805a\u96c6\u5199&#xff08;Scatter-Gather I\/O&#xff09;&#xff0c;\u5c06\u591a\u4e2a\u4e0d\u8fde\u7eed\u7684\u5185\u5b58\u5757\u4e00\u6b21\u6027\u4ea4\u7ed9\u5185\u6838\u53d1\u9001\u3002<\/p>\n<p>\u6838\u5fc3\u6e90\u7801\u5206\u6790 (src\/networking.c &#8211; _writevToClient)&#xff1a;<\/p>\n<p><span class=\"token keyword\">static<\/span> <span class=\"token keyword\">int<\/span> <span class=\"token function\">_writevToClient<\/span><span class=\"token punctuation\">(<\/span>client <span class=\"token operator\">*<\/span>c<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">ssize_t<\/span> <span class=\"token operator\">*<\/span>nwritten<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/* 1. \u51c6\u5907 IO \u5411\u91cf\u6570\u7ec4 *\/<\/span><br \/>\n    <span class=\"token comment\">\/* IOV_MAX \u901a\u5e38\u662f 1024&#xff0c;\u9650\u5236\u5355\u6b21\u7cfb\u7edf\u8c03\u7528\u6d89\u53ca\u7684\u5185\u5b58\u5757\u6570\u91cf *\/<\/span><br \/>\n    <span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">iovec<\/span> iov<span class=\"token punctuation\">[<\/span>IOV_MAX<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> iovcnt <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token class-name\">size_t<\/span> iov_bytes_len <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/* 2. \u88c5\u8f7d\u9759\u6001\u7f13\u51b2\u533a (Static Buffer) *\/<\/span><br \/>\n    <span class=\"token comment\">\/* \u5982\u679c c-&gt;buf \u6709\u6570\u636e&#xff0c;\u5b83\u603b\u662f\u4f5c\u4e3a\u7b2c\u4e00\u4e2a\u5757 *\/<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>bufpos <span class=\"token operator\">&gt;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        iov<span class=\"token punctuation\">[<\/span>iovcnt<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>iov_base <span class=\"token operator\">&#061;<\/span> c<span class=\"token operator\">-&gt;<\/span>buf <span class=\"token operator\">&#043;<\/span> c<span class=\"token operator\">-&gt;<\/span>sentlen<span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u52a0\u4e0a\u5df2\u53d1\u9001\u504f\u79fb\u91cf<\/span><br \/>\n        iov<span class=\"token punctuation\">[<\/span>iovcnt<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>iov_len <span class=\"token operator\">&#061;<\/span> c<span class=\"token operator\">-&gt;<\/span>bufpos <span class=\"token operator\">&#8211;<\/span> c<span class=\"token operator\">-&gt;<\/span>sentlen<span class=\"token punctuation\">;<\/span><br \/>\n        iov_bytes_len <span class=\"token operator\">&#043;&#061;<\/span> iov<span class=\"token punctuation\">[<\/span>iovcnt<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>iov_len<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/* 3. \u88c5\u8f7d\u52a8\u6001\u94fe\u8868 (Dynamic Reply List) *\/<\/span><br \/>\n    listIter iter<span class=\"token punctuation\">;<\/span><br \/>\n    listNode <span class=\"token operator\">*<\/span>next<span class=\"token punctuation\">;<\/span><br \/>\n    clientReplyBlock <span class=\"token operator\">*<\/span>o<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token function\">listRewind<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>reply<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>iter<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/* \u904d\u5386\u94fe\u8868&#xff0c;\u586b\u5145 iov \u6570\u7ec4&#xff0c;\u76f4\u5230\u586b\u6ee1 IOV_MAX \u6216\u8fbe\u5230\u5355\u6b21\u5199\u5165\u4e0a\u9650 *\/<\/span><br \/>\n    <span class=\"token keyword\">while<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>next <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">listNext<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>iter<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&amp;&amp;<\/span> iovcnt <span class=\"token operator\">&lt;<\/span> IOV_MAX <span class=\"token operator\">&amp;&amp;<\/span> iov_bytes_len <span class=\"token operator\">&lt;<\/span> NET_MAX_WRITES_PER_EVENT<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        o <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">listNodeValue<\/span><span class=\"token punctuation\">(<\/span>next<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>o<span class=\"token operator\">-&gt;<\/span>used <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token comment\">\/* \u8df3\u8fc7\u7a7a\u8282\u70b9\u5e76\u6e05\u7406 *\/<\/span><br \/>\n            <span class=\"token function\">listDelNode<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>reply<span class=\"token punctuation\">,<\/span> next<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">continue<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        iov<span class=\"token punctuation\">[<\/span>iovcnt<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>iov_base <span class=\"token operator\">&#061;<\/span> o<span class=\"token operator\">-&gt;<\/span>buf<span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u6307\u5411\u94fe\u8868\u8282\u70b9\u7684\u7f13\u51b2\u533a<\/span><br \/>\n        iov<span class=\"token punctuation\">[<\/span>iovcnt<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>iov_len <span class=\"token operator\">&#061;<\/span> o<span class=\"token operator\">-&gt;<\/span>used<span class=\"token punctuation\">;<\/span><br \/>\n        iov_bytes_len <span class=\"token operator\">&#043;&#061;<\/span> iov<span class=\"token punctuation\">[<\/span>iovcnt<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>iov_len<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/* 4. \u6267\u884c\u7cfb\u7edf\u8c03\u7528 *\/<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>iovcnt <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">return<\/span> C_OK<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token operator\">*<\/span>nwritten <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">connWritev<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>conn<span class=\"token punctuation\">,<\/span> iov<span class=\"token punctuation\">,<\/span> iovcnt<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u5e95\u5c42\u8c03\u7528 writev<\/span><\/p>\n<p>    <span class=\"token comment\">\/* &#8230; \u540e\u7eed\u5904\u7406 &#8230; *\/<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u6280\u672f\u4eae\u70b9&#xff1a;<\/p>\n<ul>\n<li>\u51cf\u5c11 Syscall&#xff1a;\u5c06\u6700\u591a IOV_MAX&#xff08;\u901a\u5e38 1024&#xff09;\u4e2a\u5185\u5b58\u5757\u5408\u5e76\u4e3a\u4e00\u6b21\u7cfb\u7edf\u8c03\u7528\u3002\u5bf9\u4e8e list range \u6216\u5927\u5bf9\u8c61\u83b7\u53d6\u8fd9\u7c7b\u4ea7\u751f\u5927\u91cf\u788e\u7247\u7684\u547d\u4ee4&#xff0c;\u541e\u5410\u91cf\u63d0\u5347\u663e\u8457\u3002<\/li>\n<li>\u5185\u5b58\u96f6\u62f7\u8d1d&#xff1a;writev \u76f4\u63a5\u8bfb\u53d6\u5404\u4e2a\u5185\u5b58\u5757&#xff0c;\u65e0\u9700\u5148\u5c06\u6570\u636e\u62f7\u8d1d\u5230\u4e00\u4e2a\u5927\u7684\u8fde\u7eed buffer \u4e2d\u518d\u53d1\u9001\u3002<\/li>\n<\/ul>\n<h3>7.2 \u515c\u5e95\u673a\u5236&#xff1a;\u5199\u4e8b\u4ef6\u56de\u8c03 sendReplyToClient<\/h3>\n<p>\u5728\u7edd\u5927\u591a\u6570\u60c5\u51b5\u4e0b&#xff0c;Redis \u5e0c\u671b\u5728 beforeSleep \u9636\u6bb5\u901a\u8fc7\u76f4\u63a5\u8c03\u7528 writeToClient&#xff08;Fast Path&#xff09;\u628a\u6570\u636e\u53d1\u5b8c&#xff0c;\u4ece\u800c\u907f\u514d\u6ce8\u518c\u6587\u4ef6\u4e8b\u4ef6\u7684\u5f00\u9500\u3002<\/p>\n<p>\u4f46\u5982\u679c\u5ba2\u6237\u7aef\u63a5\u6536\u6162&#xff0c;\u6216\u8005\u6570\u636e\u91cf\u8fc7\u5927\u5bfc\u81f4\u5185\u6838 Socket \u53d1\u9001\u7f13\u51b2\u533a\u6ee1&#xff08;EAGAIN&#xff09;&#xff0c;\u6570\u636e\u5c31\u4f1a\u6b8b\u7559\u3002\u6b64\u65f6 Redis \u5fc5\u987b\u9000\u56de\u5230\u6807\u51c6\u7684\u4e8b\u4ef6\u9a71\u52a8\u6a21\u5f0f\u3002<\/p>\n<p>\u6ce8\u518c\u903b\u8f91 (src\/networking.c &#8211; handleClientsWithPendingWrites)&#xff1a;<\/p>\n<p><span class=\"token comment\">\/* \u5982\u679c\u5c1d\u8bd5\u76f4\u63a5\u5199\u4e4b\u540e\u8fd8\u6709\u5269\u4f59\u6570\u636e *\/<\/span><br \/>\n<span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token function\">clientHasPendingReplies<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/* \u6ce8\u518c AE_WRITABLE \u4e8b\u4ef6&#xff0c;\u7ed1\u5b9a\u56de\u8c03\u51fd\u6570 sendReplyToClient *\/<\/span><br \/>\n    <span class=\"token function\">installClientWriteHandler<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u56de\u8c03\u903b\u8f91 (src\/networking.c &#8211; sendReplyToClient)&#xff1a; \u5f53 EventLoop \u68c0\u6d4b\u5230 Socket \u53ef\u5199\u65f6&#xff0c;\u89e6\u53d1\u6b64\u56de\u8c03&#xff1a;<\/p>\n<p><span class=\"token keyword\">void<\/span> <span class=\"token function\">sendReplyToClient<\/span><span class=\"token punctuation\">(<\/span>connection <span class=\"token operator\">*<\/span>conn<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    client <span class=\"token operator\">*<\/span>c <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">connGetPrivateData<\/span><span class=\"token punctuation\">(<\/span>conn<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token comment\">\/* \u7b2c\u4e8c\u4e2a\u53c2\u6570 handler_installed &#061; 1 *\/<\/span><br \/>\n    <span class=\"token function\">writeToClient<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">,<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u72b6\u6001\u673a\u95ed\u73af&#xff1a; writeToClient \u5185\u90e8\u4f1a\u518d\u6b21\u5c1d\u8bd5\u53d1\u9001\u3002\u5982\u679c\u8fd9\u6b21\u53d1\u5b8c\u4e86&#xff0c;\u5b83\u4f1a\u4e3b\u52a8\u8c03\u7528 connSetWriteHandler(c-&gt;conn, NULL) \u79fb\u9664\u5199\u4e8b\u4ef6\u76d1\u542c\u3002\u8fd9\u79cd\u201c\u6309\u9700\u6ce8\u518c&#xff0c;\u7528\u5b8c\u5373\u5f03\u201d\u7684\u7b56\u7565\u662f Redis \u4fdd\u6301 EventLoop \u9ad8\u6548\u7684\u5173\u952e\u3002<\/p>\n<h3>7.3 \u5b89\u5168\u9632\u7ebf&#xff1a;\u8f93\u51fa\u7f13\u51b2\u533a\u9650\u5236&#xff08;Output Buffer Limits&#xff09;<\/h3>\n<p>\u5982\u679c\u5ba2\u6237\u7aef&#xff08;\u6d88\u8d39\u8005&#xff09;\u5904\u7406\u901f\u5ea6\u8fdc\u6162\u4e8e Redis&#xff08;\u751f\u4ea7\u8005&#xff09;&#xff0c;\u6216\u8005\u67d0\u4e2a\u5ba2\u6237\u7aef\u6267\u884c\u4e86 MONITOR \u547d\u4ee4&#xff0c;\u8f93\u51fa\u7f13\u51b2\u533a&#xff08;\u7279\u522b\u662f c-&gt;reply \u94fe\u8868&#xff09;\u4f1a\u65e0\u9650\u81a8\u80c0&#xff0c;\u6700\u7ec8\u5bfc\u81f4 Redis OOM&#xff08;\u5185\u5b58\u6ea2\u51fa&#xff09;\u3002<\/p>\n<p>Redis 8.4 \u901a\u8fc7 checkClientOutputBufferLimits \u5b9e\u65bd\u4e25\u683c\u7684\u81ea\u6211\u4fdd\u62a4\u3002<\/p>\n<p>\u68c0\u6d4b\u903b\u8f91 (src\/networking.c)&#xff1a;<\/p>\n<p><span class=\"token keyword\">int<\/span> <span class=\"token function\">checkClientOutputBufferLimits<\/span><span class=\"token punctuation\">(<\/span>client <span class=\"token operator\">*<\/span>c<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/* \u8ba1\u7b97\u5f53\u524d\u7f13\u51b2\u533a\u603b\u5927\u5c0f (buf &#043; reply list) *\/<\/span><br \/>\n    <span class=\"token keyword\">unsigned<\/span> <span class=\"token keyword\">long<\/span> used_mem <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">getClientOutputBufferMemoryUsage<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/* \u83b7\u53d6\u914d\u7f6e\u9650\u5236 (client-output-buffer-limit) *\/<\/span><br \/>\n    <span class=\"token comment\">\/\/ class \u5206\u4e3a NORMAL, SLAVE, PUBSUB<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> class <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">getClientType<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token class-name\">size_t<\/span> hard_limit <span class=\"token operator\">&#061;<\/span> server<span class=\"token punctuation\">.<\/span>client_obuf_limits<span class=\"token punctuation\">[<\/span>class<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>hard_limit_bytes<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token class-name\">size_t<\/span> soft_limit <span class=\"token operator\">&#061;<\/span> server<span class=\"token punctuation\">.<\/span>client_obuf_limits<span class=\"token punctuation\">[<\/span>class<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>soft_limit_bytes<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/* 1. \u786c\u9650\u5236\u68c0\u67e5 (Hard Limit) *\/<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>hard_limit <span class=\"token operator\">&amp;&amp;<\/span> used_mem <span class=\"token operator\">&gt;&#061;<\/span> hard_limit<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u7acb\u5373\u65ad\u5f00<\/span><\/p>\n<p>    <span class=\"token comment\">\/* 2. \u8f6f\u9650\u5236\u68c0\u67e5 (Soft Limit) *\/<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>soft_limit <span class=\"token operator\">&amp;&amp;<\/span> used_mem <span class=\"token operator\">&gt;&#061;<\/span> soft_limit<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>obuf_soft_limit_reached_time <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token comment\">\/* \u7b2c\u4e00\u6b21\u89e6\u8fbe&#xff0c;\u8bb0\u5f55\u65f6\u95f4 *\/<\/span><br \/>\n            c<span class=\"token operator\">-&gt;<\/span>obuf_soft_limit_reached_time <span class=\"token operator\">&#061;<\/span> server<span class=\"token punctuation\">.<\/span>unixtime<span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u6682\u65f6\u653e\u8fc7<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token comment\">\/* \u68c0\u67e5\u6301\u7eed\u65f6\u95f4\u662f\u5426\u8d85\u8fc7\u9608\u503c *\/<\/span><br \/>\n            <span class=\"token class-name\">time_t<\/span> elapsed <span class=\"token operator\">&#061;<\/span> server<span class=\"token punctuation\">.<\/span>unixtime <span class=\"token operator\">&#8211;<\/span> c<span class=\"token operator\">-&gt;<\/span>obuf_soft_limit_reached_time<span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>elapsed <span class=\"token operator\">&gt;<\/span> server<span class=\"token punctuation\">.<\/span>client_obuf_limits<span class=\"token punctuation\">[<\/span>class<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>soft_limit_seconds<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u6301\u7eed\u8d85\u6807&#xff0c;\u65ad\u5f00<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        c<span class=\"token operator\">-&gt;<\/span>obuf_soft_limit_reached_time <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u6062\u590d\u6b63\u5e38&#xff0c;\u91cd\u7f6e\u8ba1\u65f6\u5668<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u4fdd\u62a4\u673a\u5236&#xff1a;\u4e00\u65e6\u8be5\u51fd\u6570\u8fd4\u56de 1&#xff0c;Redis \u4f1a\u7acb\u5373\u8c03\u7528 freeClientAsync(c) \u5f3a\u5236\u65ad\u5f00\u8fde\u63a5&#xff0c;\u5e76\u5728\u65e5\u5fd7\u4e2d\u6253\u5370 Client closed for overcoming of output buffer limits&#xff0c;\u9632\u6b62\u5355\u70b9\u6545\u969c\u62d6\u57ae\u6574\u4e2a\u5b9e\u4f8b\u3002<\/p>\n<h3>7.4 \u5185\u5b58\u56de\u6536\u7b56\u7565&#xff1a;\u6570\u636e\u6e38\u6807\u7684\u63a8\u8fdb<\/h3>\n<p>\u5f53 writev \u6210\u529f\u8fd4\u56de nwritten \u5b57\u8282\u540e&#xff0c;Redis \u9700\u8981\u7cbe\u786e\u5730\u6e05\u7406\u5df2\u53d1\u9001\u7684\u6570\u636e&#xff0c;\u91ca\u653e\u5185\u5b58\u3002<\/p>\n<p>\u6e05\u7406\u6d41\u7a0b (src\/networking.c &#8211; _writevToClient \u540e\u534a\u90e8\u5206)&#xff1a;<\/p>\n<li>\n<p>\u6d88\u8017\u9759\u6001\u7f13\u51b2\u533a&#xff1a; \u9996\u5148\u6263\u51cf c-&gt;buf\u3002\u5982\u679c nwritten \u5927\u4e8e c-&gt;bufpos&#xff0c;\u8bf4\u660e\u9759\u6001\u533a\u53d1\u5b8c\u4e86&#xff0c;\u91cd\u7f6e c-&gt;bufpos &#061; 0&#xff0c;\u5269\u4f59\u7684 nwritten \u7ee7\u7eed\u7528\u4e8e\u6263\u51cf\u94fe\u8868\u3002<\/p>\n<\/li>\n<li>\n<p>\u6d88\u8017\u52a8\u6001\u94fe\u8868&#xff1a; \u904d\u5386 c-&gt;reply \u94fe\u8868&#xff0c;\u9010\u4e2a\u8282\u70b9\u6263\u51cf\u3002<\/p>\n<p> <span class=\"token function\">listRewind<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>reply<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>iter<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token keyword\">while<\/span> <span class=\"token punctuation\">(<\/span>remaining <span class=\"token operator\">&gt;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    next <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">listNext<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>iter<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    o <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">listNodeValue<\/span><span class=\"token punctuation\">(<\/span>next<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/* \u5982\u679c\u5f53\u524d\u8282\u70b9\u88ab\u5b8c\u5168\u53d1\u9001 *\/<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>remaining <span class=\"token operator\">&gt;&#061;<\/span> o<span class=\"token operator\">-&gt;<\/span>used<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        remaining <span class=\"token operator\">-&#061;<\/span> o<span class=\"token operator\">-&gt;<\/span>used<span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token function\">listDelNode<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>reply<span class=\"token punctuation\">,<\/span> next<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u5173\u952e&#xff1a;\u91ca\u653e\u8282\u70b9\u5185\u5b58 (zfree)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/* \u5f53\u524d\u8282\u70b9\u53ea\u53d1\u4e86\u4e00\u90e8\u5206&#xff0c;\u4fee\u6539\u504f\u79fb\u91cf&#xff0c;\u4e0b\u6b21\u7ee7\u7eed\u53d1 *\/<\/span><br \/>\n        <span class=\"token comment\">\/* \u6ce8\u610f&#xff1a;\u8fd9\u91cc\u5e76\u6ca1\u6709 memmove&#xff0c;\u800c\u662f\u901a\u8fc7\u504f\u79fb\u91cf\u903b\u8f91\u5904\u7406&#xff0c;\u907f\u514d\u5185\u5b58\u62f7\u8d1d *\/<\/span><br \/>\n        c<span class=\"token operator\">-&gt;<\/span>sentlen <span class=\"token operator\">&#043;&#061;<\/span> remaining<span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">break<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span>\n <\/li>\n<p>\u8fd9\u79cd\u201c\u8fb9\u53d1\u8fb9\u5220\u201d\u7684\u673a\u5236\u786e\u4fdd\u4e86 Redis \u5728\u5904\u7406\u5927\u6570\u636e\u4f20\u8f93\u65f6&#xff0c;\u5185\u5b58\u5360\u7528\u80fd\u591f\u968f\u7740\u7f51\u7edc\u53d1\u9001\u5373\u65f6\u4e0b\u964d&#xff0c;\u800c\u4e0d\u662f\u7b49\u5230\u6240\u6709\u6570\u636e\u53d1\u5b8c\u624d\u7edf\u4e00\u91ca\u653e\u3002<\/p>\n<h2>\u7b2c\u516b\u90e8\u5206&#xff1a;Redis 8.4 \u9488\u5bf9\u9ad8\u5e76\u53d1 IO \u7684\u5e95\u5c42\u5fae\u8c03<\/h2>\n<p>\u5728\u9ad8\u5e76\u53d1 IO \u573a\u666f\u4e0b&#xff0c;\u74f6\u9888\u5f80\u5f80\u4ece\u7f51\u7edc\u5e26\u5bbd\u8f6c\u79fb\u5230\u4e86 CPU \u7f13\u5b58\u547d\u4e2d\u7387&#xff08;Cache Hit Rate&#xff09; \u548c \u5185\u5b58\u5206\u914d\u5668&#xff08;Allocator&#xff09; \u7684\u5f00\u9500\u4e0a\u3002Redis 8.4 \u5728\u8fd9\u65b9\u9762\u8fdb\u884c\u4e86\u6781\u5ea6\u514b\u5236\u7684\u5e95\u5c42\u4f18\u5316\u3002<\/p>\n<h3>8.1 \u7f13\u51b2\u533a\u5206\u914d\u5668\u7684\u6539\u8fdb&#xff1a;\u5bf9\u5185\u5b58\u5bf9\u9f50\u4e0e Cache Line \u7684\u5229\u7528<\/h3>\n<p>Redis \u5728\u521b\u5efa\u5ba2\u6237\u7aef\u65f6&#xff0c;\u9700\u8981\u9891\u7e41\u7533\u8bf7\u8f93\u5165\u8f93\u51fa\u7f13\u51b2\u533a\u3002Redis 8.4 \u901a\u8fc7\u5de7\u5999\u5229\u7528\u5185\u5b58\u5206\u914d\u5668\u7684\u7279\u6027&#xff0c;\u69a8\u5e72\u4e86\u6bcf\u4e00\u4e2a\u5b57\u8282\u3002<\/p>\n<h4>8.1.1. zmalloc_usable&#xff1a;\u69a8\u5e72\u788e\u7247\u7a7a\u95f4<\/h4>\n<p>\u5728 createClient \u4e2d&#xff0c;Redis \u7533\u8bf7\u9759\u6001\u8f93\u51fa\u7f13\u51b2\u533a\u65f6&#xff0c;\u5e76\u4e0d\u4ec5\u4ec5\u662f\u7533\u8bf7\u56fa\u5b9a\u7684 16KB&#xff1a;<\/p>\n<p><span class=\"token comment\">\/* src\/networking.c &#8211; createClient *\/<\/span><br \/>\nc<span class=\"token operator\">-&gt;<\/span>buf <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">zmalloc_usable<\/span><span class=\"token punctuation\">(<\/span>PROTO_REPLY_CHUNK_BYTES<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>c<span class=\"token operator\">-&gt;<\/span>buf_usable_size<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<ul>\n<li>\u539f\u7406&#xff1a;\u867d\u7136\u5b8f PROTO_REPLY_CHUNK_BYTES \u5b9a\u4e49\u4e3a 16KB&#xff0c;\u4f46\u5e95\u5c42\u7684\u5206\u914d\u5668&#xff08;jemalloc\/tcmalloc&#xff09;\u4e3a\u4e86\u5185\u5b58\u5bf9\u9f50&#xff0c;\u901a\u5e38\u4f1a\u5206\u914d\u6bd4\u8bf7\u6c42\u7a0d\u5927\u4e00\u70b9\u7684\u5185\u5b58\u5757&#xff08;\u4f8b\u5982\u8bf7\u6c42 16384 \u5b57\u8282&#xff0c;\u5b9e\u9645\u5206\u914d 16400 \u5b57\u8282&#xff09;\u3002<\/li>\n<li>\u4f18\u5316&#xff1a;zmalloc_usable \u4f1a\u8fd4\u56de\u5b9e\u9645\u5206\u914d\u7684\u5927\u5c0f&#xff0c;\u5e76\u5c06\u5176\u5b58\u5165 c-&gt;buf_usable_size\u3002Redis \u636e\u6b64\u8c03\u6574\u7f13\u51b2\u533a\u8fb9\u754c\u3002<\/li>\n<li>\u6536\u76ca&#xff1a;\u5728\u9ad8\u5e76\u53d1\u4e0b&#xff0c;\u8fd9\u610f\u5473\u7740\u6bcf\u6570\u5343\u4e2a\u8fde\u63a5\u5c31\u80fd\u201c\u767d\u5ad6\u201d\u51fa\u76f8\u5f53\u53ef\u89c2\u7684\u7f13\u5b58\u7a7a\u95f4&#xff0c;\u4e14\u51cf\u5c11\u4e86\u8d8a\u754c\u98ce\u9669&#xff0c;\u5b8c\u5168\u6d88\u9664\u4e86\u5185\u90e8\u788e\u7247\u6d6a\u8d39\u3002<\/li>\n<\/ul>\n<h4>8.1.2. \u975e\u8d2a\u5a6a\u5f0f\u6269\u5bb9 (sdsMakeRoomForNonGreedy)<\/h4>\n<p>\u5728 readQueryFromClient \u4e2d&#xff0c;IO \u7ebf\u7a0b\u8bfb\u53d6\u6570\u636e\u5230\u8f93\u5165\u7f13\u51b2\u533a querybuf \u65f6&#xff0c;\u4f7f\u7528\u4e86\u7279\u6b8a\u7684\u6269\u5bb9\u7b56\u7565&#xff1a;<\/p>\n<p><span class=\"token comment\">\/* src\/networking.c &#8211; readQueryFromClient *\/<\/span><br \/>\n<span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/* \u4f7f\u7528\u975e\u8d2a\u5a6a\u6a21\u5f0f\u6269\u5bb9&#xff0c;\u907f\u514d\u5206\u914d\u8fc7\u591a\u5185\u5b58\u5bfc\u81f4\u9891\u7e41\u7684 Cache Miss *\/<\/span><br \/>\n    c<span class=\"token operator\">-&gt;<\/span>querybuf <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">sdsMakeRoomForNonGreedy<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>querybuf<span class=\"token punctuation\">,<\/span> readlen<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/* \u666e\u901a\u6a21\u5f0f&#xff1a;\u6307\u6570\u7ea7\u6269\u5bb9&#xff08;2\u500d&#xff09; *\/<\/span><br \/>\n    c<span class=\"token operator\">-&gt;<\/span>querybuf <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">sdsMakeRoomFor<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>querybuf<span class=\"token punctuation\">,<\/span> readlen<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<ul>\n<li>\u573a\u666f&#xff1a;\u5bf9\u4e8e\u5927\u6570\u636e\u5305&#xff08;Big Arg&#xff09;&#xff0c;Redis 8.4 \u653e\u5f03\u4e86\u4f20\u7edf\u7684\u6307\u6570\u7ea7&#xff08;x2&#xff09;\u9884\u5206\u914d&#xff0c;\u6539\u7528\u201c\u591f\u7528\u5c31\u597d\u201d\u7684\u7b56\u7565\u3002<\/li>\n<li>\u6536\u76ca&#xff1a;\u8fd9\u907f\u514d\u4e86\u5904\u7406\u5927\u8bf7\u6c42\u65f6 querybuf \u77ac\u95f4\u81a8\u80c0\u5bfc\u81f4\u5927\u91cf\u7269\u7406\u5185\u5b58\u9875&#xff08;Page&#xff09;\u88ab\u89e6\u78b0&#xff0c;\u4ece\u800c\u964d\u4f4e\u4e86 TLB&#xff08;Translation Lookaside Buffer&#xff09;Miss \u7684\u6982\u7387\u3002<\/li>\n<\/ul>\n<h3>8.2 client \u7ed3\u6784\u4f53\u5b57\u6bb5\u91cd\u6392&#xff1a;\u51cf\u5c11\u7f13\u5b58\u884c\u5931\u6548&#xff08;Cache Miss&#xff09;<\/h3>\n<p>\u867d\u7136\u5177\u4f53\u7684\u7ed3\u6784\u4f53\u5b9a\u4e49\u5728 server.h&#xff0c;\u4f46\u5728 Redis 8.4 \u7684\u4ee3\u7801\u903b\u8f91\u4e2d&#xff0c;\u53ef\u4ee5\u660e\u663e\u770b\u5230\u5bf9 \u70ed\u70b9\u5b57\u6bb5&#xff08;Hot Fields&#xff09;\u7684\u8bbf\u95ee\u805a\u96c6\u6027\u4f18\u5316\u3002<\/p>\n<h4>CPU Cache Line \u4eb2\u548c\u6027\u8bbe\u8ba1<\/h4>\n<p>CPU \u8bfb\u53d6\u5185\u5b58\u4e0d\u662f\u4e00\u4e2a\u5b57\u8282\u4e00\u4e2a\u5b57\u8282\u8bfb&#xff0c;\u800c\u662f\u4e00\u6b21\u8bfb\u53d6\u4e00\u4e2a Cache Line&#xff08;\u901a\u5e38 64 \u5b57\u8282&#xff09;\u3002<\/p>\n<p>\u5728 readQueryFromClient \u548c writeToClient \u8fd9\u4e24\u4e2a\u6700\u9ad8\u9891\u7684\u51fd\u6570\u4e2d&#xff0c;\u4ee3\u7801\u5bf9 client \u7ed3\u6784\u4f53\u7684\u8bbf\u95ee\u9ad8\u5ea6\u96c6\u4e2d\u5728\u4ee5\u4e0b\u5b57\u6bb5&#xff1a;<\/p>\n<ul>\n<li>c-&gt;conn (\u8fde\u63a5\u6307\u9488)<\/li>\n<li>c-&gt;bufpos (\u9759\u6001\u7f13\u51b2\u504f\u79fb)<\/li>\n<li>c-&gt;buf (\u9759\u6001\u7f13\u51b2\u6307\u9488)<\/li>\n<li>c-&gt;querybuf (\u8f93\u5165\u7f13\u51b2\u6307\u9488)<\/li>\n<li>c-&gt;flags (\u72b6\u6001\u6807\u8bb0)<\/li>\n<\/ul>\n<p>\u4ee3\u7801\u903b\u8f91\u4f53\u73b0&#xff1a; Redis \u5f00\u53d1\u8005\u5728\u8bbe\u8ba1\u65f6&#xff0c;\u6709\u610f\u5c06\u8fd9\u4e9b\u5b57\u6bb5\u5728\u5185\u5b58\u5e03\u5c40\u4e0a\u7d27\u5bc6\u6392\u5217\u3002\u5f53 CPU \u8bfb\u53d6 c-&gt;conn \u51c6\u5907\u8fdb\u884c\u7cfb\u7edf\u8c03\u7528\u65f6&#xff0c;c-&gt;buf \u548c c-&gt;flags \u5f88\u53ef\u80fd\u5df2\u7ecf\u88ab\u81ea\u52a8\u52a0\u8f7d\u5230\u4e86 L1 Cache \u4e2d\u3002<\/p>\n<ul>\n<li>\u53cd\u4f8b&#xff1a;\u5982\u679c c-&gt;name&#xff08;\u5f88\u5c11\u8bbf\u95ee&#xff09;\u63d2\u5728 c-&gt;conn \u548c c-&gt;buf \u4e2d\u95f4&#xff0c;\u5c31\u4f1a\u5bfc\u81f4 CPU \u52a0\u8f7d\u65e0\u7528\u6570\u636e&#xff0c;\u6d6a\u8d39\u5b9d\u8d35\u7684 Cache \u7a7a\u95f4\u3002<\/li>\n<\/ul>\n<h3>8.3 \u5f02\u5e38\u8fde\u63a5\u7684\u5feb\u901f\u6536\u5272\u903b\u8f91&#xff1a;freeClient \u4e0e\u9500\u6bc1\u6d41\u7a0b<\/h3>\n<p>\u5728\u9ad8\u5e76\u53d1\u573a\u666f\u4e0b&#xff0c;\u5ba2\u6237\u7aef\u7684\u8fde\u63a5\u548c\u65ad\u5f00&#xff08;Churn Rate&#xff09;\u975e\u5e38\u9891\u7e41\u3002\u5982\u679c\u9500\u6bc1\u6d41\u7a0b\u592a\u6162&#xff0c;\u4f1a\u5bfc\u81f4 fd \u8017\u5c3d\u6216\u5185\u5b58\u6cc4\u6f0f\u3002Redis 8.4 \u5f15\u5165\u4e86 \u5f02\u6b65\u60f0\u6027\u91ca\u653e&#xff08;Async Lazy Free&#xff09;\u673a\u5236\u3002<\/p>\n<h4>8.3.1. freeClientAsync&#xff1a;\u5b89\u5168\u5730\u201c\u5224\u6b7b\u5211\u201d<\/h4>\n<p>\u5728\u591a\u7ebf\u7a0b\u73af\u5883\u4e0b&#xff0c;\u76f4\u63a5\u91ca\u653e\u4e00\u4e2a\u53ef\u80fd\u6b63\u88ab IO \u7ebf\u7a0b\u64cd\u4f5c\u7684 Client \u662f\u6781\u5ea6\u5371\u9669\u7684&#xff08;\u4f1a\u5bfc\u81f4 Segfault&#xff09;\u3002<\/p>\n<p>\u6e90\u7801\u5206\u6790 (src\/networking.c &#8211; freeClientAsync)&#xff1a;<\/p>\n<p><span class=\"token keyword\">void<\/span> <span class=\"token function\">freeClientAsync<\/span><span class=\"token punctuation\">(<\/span>client <span class=\"token operator\">*<\/span>c<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/* 1. \u7ebf\u7a0b\u5b89\u5168\u68c0\u67e5 *\/<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>running_tid <span class=\"token operator\">!&#061;<\/span> IOTHREAD_MAIN_THREAD_ID<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/* \u5982\u679c Client \u6b63\u88ab IO \u7ebf\u7a0b\u6301\u6709&#xff0c;\u4e0d\u80fd\u76f4\u63a5\u5220&#xff01; *\/<\/span><br \/>\n        <span class=\"token comment\">\/* \u6807\u8bb0\u4e3a\u7531 IO \u7ebf\u7a0b\u5173\u95ed&#xff0c;\u5e76\u63a8\u56de\u4e3b\u7ebf\u7a0b\u961f\u5217 *\/<\/span><br \/>\n        c<span class=\"token operator\">-&gt;<\/span>io_flags <span class=\"token operator\">|&#061;<\/span> CLIENT_IO_CLOSE_ASAP<span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token function\">enqueuePendingClientsToMainThread<\/span><span class=\"token punctuation\">(<\/span>c<span class=\"token punctuation\">,<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/* 2. \u6807\u8bb0\u4e3a\u5c3d\u5feb\u5173\u95ed *\/<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>c<span class=\"token operator\">-&gt;<\/span>flags <span class=\"token operator\">&amp;<\/span> CLIENT_CLOSE_ASAP<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    c<span class=\"token operator\">-&gt;<\/span>flags <span class=\"token operator\">|&#061;<\/span> CLIENT_CLOSE_ASAP<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/* 3. \u52a0\u5165\u201c\u6b7b\u4ea1\u540d\u5355\u201d *\/<\/span><br \/>\n    <span class=\"token function\">listAddNodeTail<\/span><span class=\"token punctuation\">(<\/span>server<span class=\"token punctuation\">.<\/span>clients_to_close<span class=\"token punctuation\">,<\/span> c<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>8.3.2. \u6279\u91cf\u6536\u5272 (freeClientsInAsyncFreeQueue)<\/h4>\n<p>\u4e3b\u7ebf\u7a0b\u4e0d\u4f1a\u5728\u68c0\u6d4b\u5230\u9519\u8bef\u65f6\u7acb\u5373\u8c03\u7528 free&#xff08;\u7cfb\u7edf\u8c03\u7528\u5f00\u9500\u5927&#xff09;&#xff0c;\u800c\u662f\u5c06\u5b83\u4eec\u6302\u5728 clients_to_close \u94fe\u8868\u4e0a\u3002 \u5728 beforeSleep \u9636\u6bb5&#xff0c;\u4e3b\u7ebf\u7a0b\u4f1a\u96c6\u4e2d\u904d\u5386\u8fd9\u4e2a\u94fe\u8868&#xff0c;\u6279\u91cf\u9500\u6bc1&#xff1a;<\/p>\n<ul>\n<li>\u4f18\u52bf&#xff1a;\u5229\u7528 CPU \u7684 Pipeline&#xff0c;\u6279\u91cf\u5904\u7406\u5185\u5b58\u91ca\u653e&#xff0c;\u6bd4\u201c\u96f6\u6572\u788e\u6253\u201d\u7684\u91ca\u653e\u6548\u7387\u66f4\u9ad8\u3002<\/li>\n<\/ul>\n<h4>8.3.3. freeClient \u7684\u8d44\u6e90\u89e3\u7ed1<\/h4>\n<p>\u5f53\u771f\u6b63\u6267\u884c\u9500\u6bc1\u65f6&#xff0c;freeClient \u6267\u884c\u4e86\u4e25\u683c\u7684\u8d44\u6e90\u89e3\u7ed1\u987a\u5e8f&#xff0c;\u9632\u6b62\u60ac\u6302\u6307\u9488&#xff1a;<\/p>\n<li>\u4ece IO \u7ebf\u7a0b\u5265\u79bb&#xff1a;\u5982\u679c Client \u8fd8\u6302\u5728 IO \u7ebf\u7a0b\u7684 EventLoop \u4e0a&#xff0c;\u5f3a\u5236\u89e3\u7ed1\u3002<\/li>\n<li>\u53d6\u6d88\u8ba2\u9605&#xff1a;\u89e3\u7ed1 Pub\/Sub \u5b57\u5178\u3002<\/li>\n<li>\u91ca\u653e\u7f13\u51b2\u533a&#xff1a;\u91ca\u653e querybuf\u3001c-&gt;buf\u3001c-&gt;reply \u94fe\u8868\u3002<\/li>\n<li>\u5173\u95ed Socket&#xff1a;\u6700\u540e\u624d\u5173\u95ed\u6587\u4ef6\u63cf\u8ff0\u7b26\u3002<\/li>\n<p>\u8fd9\u79cd\u201c\u6807\u8bb0-\u5f02\u6b65\u56de\u6536-\u6279\u91cf\u91ca\u653e\u201d\u7684\u7b56\u7565&#xff0c;\u786e\u4fdd\u4e86 Redis \u5728\u9762\u5bf9\u6bcf\u79d2\u6570\u4e07\u6b21\u8fde\u63a5\u65ad\u5f00\u51b2\u51fb\u65f6&#xff0c;\u4e3b\u7ebf\u7a0b\u4f9d\u7136\u80fd\u4fdd\u6301\u5e73\u6ed1\u7684\u54cd\u5e94\u6296\u52a8\u3002<\/p>\n<h2>\u7b2c\u4e5d\u90e8\u5206&#xff1a;\u603b\u7ed3&#xff1a;Redis \u7f51\u7edc\u6a21\u578b\u7684\u6f14\u8fdb\u54f2\u5b66<\/h2>\n<p>Redis 8.4 \u7684\u7f51\u7edc\u6a21\u578b\u5e76\u975e\u63a8\u5012\u91cd\u6765&#xff0c;\u800c\u662f\u5728\u4fdd\u6301\u5176\u6838\u5fc3\u8bbe\u8ba1\u54f2\u5b66&#xff08;\u7b80\u5355\u3001\u539f\u5b50\u6027&#xff09;\u7684\u524d\u63d0\u4e0b&#xff0c;\u5bf9\u6027\u80fd\u74f6\u9888\u8fdb\u884c\u7684\u201c\u624b\u672f\u5200\u5f0f\u201d\u7cbe\u51c6\u5207\u5272\u3002<\/p>\n<h3>9.1 \u4e3a\u4ec0\u4e48\u575a\u6301\u5355\u7ebf\u7a0b\u6267\u884c\u547d\u4ee4&#xff1a;\u539f\u5b50\u6027\u4e0e\u590d\u6742\u5ea6\u7684\u5e73\u8861<\/h3>\n<p>\u5728 Redis 8.4 \u5f15\u5165\u4e86\u5982\u6b64\u590d\u6742\u7684 IO \u591a\u7ebf\u7a0b\u673a\u5236&#xff08;Threaded IO&#xff09;\u540e&#xff0c;\u4f9d\u7136\u575a\u5b88 \u201c\u547d\u4ee4\u6267\u884c\u5355\u7ebf\u7a0b\u201d \u7684\u5e95\u7ebf\u3002\u8fd9\u5e76\u975e\u6280\u672f\u4e0a\u7684\u59a5\u534f&#xff0c;\u800c\u662f\u57fa\u4e8e\u6df1\u601d\u719f\u8651\u7684\u67b6\u6784\u6743\u8861\u3002<\/p>\n<h4>9.11. \u590d\u6742\u6570\u636e\u7ed3\u6784\u7684\u5e76\u53d1\u5669\u68a6<\/h4>\n<p>Redis \u4e0d\u540c\u4e8e Memcached&#xff08;\u7b80\u5355\u7684 KV&#xff09;&#xff0c;\u5b83\u62e5\u6709 Set\u3001ZSet\u3001Hash\u3001Stream \u7b49\u6781\u5176\u590d\u6742\u7684\u6570\u636e\u7ed3\u6784\u3002 \u5982\u679c\u8ba9\u591a\u7ebf\u7a0b\u5e76\u53d1\u6267\u884c\u547d\u4ee4&#xff1a;<\/p>\n<ul>\n<li>\u9501\u7c92\u5ea6\u96be\u9898&#xff1a;\u4e3a\u4e86\u4fdd\u8bc1 ZADD \u6216 LPUSH \u7684\u7ebf\u7a0b\u5b89\u5168&#xff0c;\u5fc5\u987b\u5f15\u5165\u884c\u7ea7\u9501&#xff08;Key-level Locking&#xff09;\u751a\u81f3\u66f4\u7ec6\u7c92\u5ea6\u7684\u9501\u3002\u8fd9\u4f1a\u5e26\u6765\u5de8\u5927\u7684\u9501\u7ade\u4e89&#xff08;Lock Contention&#xff09;\u548c\u4e0a\u4e0b\u6587\u5207\u6362\u5f00\u9500&#xff0c;\u6781\u5927\u5730\u62b5\u6d88\u591a\u7ebf\u7a0b\u5e26\u6765\u7684\u6536\u76ca\u3002<\/li>\n<li>\u4ee3\u7801\u590d\u6742\u5ea6\u7206\u70b8&#xff1a;Redis \u6e90\u7801\u76ee\u524d\u4f9d\u7136\u4fdd\u6301\u7740\u60ca\u4eba\u7684\u53ef\u8bfb\u6027\u3002\u4e00\u65e6\u5f15\u5165\u7ec6\u7c92\u5ea6\u9501&#xff0c;\u6b7b\u9501\u68c0\u6d4b\u548c\u5e76\u53d1\u8c03\u8bd5\u5c06\u6210\u4e3a\u5f00\u53d1\u8005\u7684\u5669\u68a6\u3002<\/li>\n<\/ul>\n<h4>9.12. \u751f\u6001\u7cfb\u7edf\u7684\u57fa\u77f3&#xff1a;\u539f\u5b50\u6027<\/h4>\n<p>Redis \u7684\u751f\u6001\u7cfb\u7edf&#xff08;Lua \u811a\u672c\u3001\u4e8b\u52a1 MULTI\/EXEC\u3001\u6a21\u5757\u7cfb\u7edf&#xff09;\u5b8c\u5168\u5efa\u7acb\u5728\u201c\u5355\u7ebf\u7a0b\u539f\u5b50\u6267\u884c\u201d\u7684\u5047\u8bbe\u4e4b\u4e0a\u3002<\/p>\n<ul>\n<li>\u73b0\u72b6&#xff1a;\u5f00\u53d1\u8005\u9ed8\u8ba4 EVAL &#034;redis.call(&#039;GET&#039;, k); redis.call(&#039;SET&#039;, k, v)&#034; \u4e2d\u95f4\u4e0d\u4f1a\u63d2\u5165\u5176\u4ed6\u547d\u4ee4\u3002<\/li>\n<li>\u4ee3\u4ef7&#xff1a;\u5982\u679c\u6539\u4e3a\u591a\u7ebf\u7a0b\u6267\u884c&#xff0c;\u8fd9\u79cd\u539f\u5b50\u6027\u4fdd\u8bc1\u5c06\u77ac\u95f4\u74e6\u89e3&#xff0c;\u6574\u4e2a Redis \u751f\u6001\u9700\u8981\u91cd\u5199\u3002<\/li>\n<\/ul>\n<h4>9.13. \u74f6\u9888\u8f6c\u79fb\u7684\u80dc\u5229<\/h4>\n<p>Redis 6.0 \u4e4b\u524d\u7684\u74f6\u9888\u5728\u4e8e\u7f51\u7edc IO&#xff08;\u8bfb\u5199 Socket \u6d88\u8017\u5927\u91cf CPU&#xff09;\u3002Redis 8.4 \u901a\u8fc7\u5c06 read\/write \u548c parse \u5265\u79bb\u7ed9 IO \u7ebf\u7a0b&#xff0c;\u6210\u529f\u5c06\u4e3b\u7ebf\u7a0b\u4ece\u201c\u642c\u8fd0\u5de5\u201d\u89e3\u653e\u4e3a\u7eaf\u7cb9\u7684\u201c\u8ba1\u7b97\u8005\u201d\u3002 \u7ed3\u8bba&#xff1a;\u5728 99% \u7684\u573a\u666f\u4e0b&#xff0c;\u7eaf\u5185\u5b58\u64cd\u4f5c\u7684 CPU \u6d88\u8017\u8fdc\u5c0f\u4e8e\u7f51\u7edc IO\u3002\u56e0\u6b64&#xff0c;IO \u591a\u7ebf\u7a0b &#043; \u6267\u884c\u5355\u7ebf\u7a0b \u662f\u5f53\u524d\u786c\u4ef6\u6761\u4ef6\u4e0b\u7684\u6700\u4f18\u89e3\u3002<\/p>\n<h3>9.2 Redis 8.4 \u5728 Linux \u73b0\u4ee3\u5185\u6838\u7279\u6027\u4e0b\u7684\u6027\u80fd\u5929\u82b1\u677f<\/h3>\n<p>\u901a\u8fc7\u6e90\u7801 src\/iothread.c&#xff0c;\u6211\u4eec\u53ef\u4ee5\u770b\u5230 Redis 8.4 \u6781\u5ea6\u538b\u69a8\u4e86\u73b0\u4ee3 Linux \u5185\u6838\u7684\u7279\u6027&#xff0c;\u51e0\u4e4e\u89e6\u53ca\u4e86\u7528\u6237\u6001\u7f51\u7edc\u7a0b\u5e8f\u7684\u6027\u80fd\u5929\u82b1\u677f\u3002<\/p>\n<h4>9.2.1. \u81ea\u9002\u5e94\u4e92\u65a5\u9501 (PTHREAD_MUTEX_ADAPTIVE_NP)<\/h4>\n<p>\u5728 initThreadedIO \u4e2d&#xff0c;Redis \u5e76\u6ca1\u6709\u4f7f\u7528\u9ed8\u8ba4\u7684\u4e92\u65a5\u9501&#xff1a;<\/p>\n<p><span class=\"token comment\">\/* src\/iothread.c *\/<\/span><br \/>\n<span class=\"token function\">pthread_mutexattr_settype<\/span><span class=\"token punctuation\">(<\/span>attr<span class=\"token punctuation\">,<\/span> PTHREAD_MUTEX_ADAPTIVE_NP<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>\u8fd9\u662f Linux \u7279\u6709\u7684\u6269\u5c55&#xff08;NP &#061; Non-Portable&#xff09;\u3002<\/p>\n<ul>\n<li>\u673a\u5236&#xff1a;\u5f53\u7ebf\u7a0b\u83b7\u53d6\u9501\u5931\u8d25\u65f6&#xff0c;\u5b83\u4e0d\u4f1a\u7acb\u5373\u8c03\u7528 futex \u7cfb\u7edf\u8c03\u7528\u8fdb\u5165\u7761\u7720&#xff08;\u8fd9\u975e\u5e38\u6162&#xff09;&#xff0c;\u800c\u662f\u5148\u5728\u7528\u6237\u6001\u81ea\u65cb&#xff08;Spinning&#xff09;\u4e00\u6bb5\u65f6\u95f4\u3002<\/li>\n<li>\u573a\u666f&#xff1a;Redis \u7684\u961f\u5217\u4ea4\u6362\u64cd\u4f5c\u6781\u5feb&#xff08;\u4ec5\u4ec5\u662f\u94fe\u8868\u6307\u9488\u79fb\u52a8&#xff09;&#xff0c;\u9501\u6301\u6709\u65f6\u95f4\u6781\u77ed\u3002\u81ea\u65cb\u9501\u907f\u514d\u4e86\u6602\u8d35\u7684\u7ebf\u7a0b\u6302\u8d77\/\u5524\u9192\u5f00\u9500&#xff0c;\u5b8c\u7f8e\u5951\u5408 Redis \u7684\u9ad8\u9891\u4ea4\u4e92\u573a\u666f\u3002<\/li>\n<\/ul>\n<h4>9.2.2. CPU \u4eb2\u548c\u6027 (sched_setaffinity)<\/h4>\n<p>Redis \u901a\u8fc7 redisSetCpuAffinity \u5f3a\u5236\u5c06 IO \u7ebf\u7a0b\u7ed1\u5b9a\u5230\u7279\u5b9a\u7684 CPU \u6838\u5fc3\u3002<\/p>\n<ul>\n<li>\u6536\u76ca&#xff1a;\u8fd9\u786e\u4fdd\u4e86\u6bcf\u4e2a IO \u7ebf\u7a0b\u72ec\u5360 L1\/L2 \u7f13\u5b58&#xff0c;\u6781\u5927\u51cf\u5c11\u4e86 Cache Miss&#xff0c;\u4f7f\u5f97\u5904\u7406\u5ef6\u8fdf\u66f4\u52a0\u786e\u5b9a&#xff08;Deterministic&#xff09;\u3002<\/li>\n<\/ul>\n<h4>9.2.3. \u805a\u96c6\u5199 (writev) \u4e0e \u96f6\u62f7\u8d1d<\/h4>\n<p>\u901a\u8fc7 struct iovec \u5c06\u9759\u6001\u7f13\u51b2\u533a\u548c\u52a8\u6001\u94fe\u8868\u805a\u5408\u53d1\u9001&#xff0c;Redis \u51cf\u5c11\u4e86\u7cfb\u7edf\u8c03\u7528\u6b21\u6570&#xff0c;\u5e76\u5229\u7528\u5185\u6838\u80fd\u529b\u907f\u514d\u4e86\u7528\u6237\u6001\u7684\u591a\u6b21\u6570\u636e\u642c\u8fd0\u3002<\/p>\n<h3>9.3 \u6e90\u7801\u9605\u8bfb\u5efa\u8bae&#xff1a;\u5982\u4f55\u8ddf\u8e2a\u4e00\u6b21\u5b8c\u6574\u7684\u4ea4\u4e92\u6d41\u7a0b&#xff08;GDB \u5b9e\u6218\u6280\u5de7&#xff09;<\/h3>\n<p>\u8fd9\u91cc\u5efa\u8bae\u79fb\u6b65\u6211 21\u5e74\u5199\u7684\u535a\u5ba2\u300aLinux \u4e2d gdb \u8c03\u8bd5 Redis\u300b,\u8fd9\u91cc\u5c31\u4e0d\u5728\u8d58\u8ff0\u4e86\u3002<\/p>\n<h2>\u7b2c\u5341\u90e8\u5206&#xff1a;\u5ef6\u4f38\u601d\u8003&#xff1a;Redis \u7f51\u7edc\u6a21\u578b vs Go Netpoller<\/h2>\n<p>\u524d\u6bb5\u65f6\u95f4\u5199\u4e86\u300aGo \u8bed\u8a00\u5982\u4f55\u5b9e\u73b0\u9ad8\u6027\u80fd\u7f51\u7edc I\/O&#xff1a;Netpoller \u6a21\u578b\u63ed\u79d8\u300b&#xff0c;\u611f\u89c9\u53ef\u4ee5\u548c Reids \u7684\u7f51\u7edc\u6a21\u578b\u6bd4\u6bd4\u3002\u6bd5\u7adf\u5728\u73b0\u4ee3\u9ad8\u5e76\u53d1\u67b6\u6784\u4e2d&#xff0c;Go (Netpoller &#043; GMP) \u548c Redis (Threaded IO) \u4ee3\u8868\u4e86\u4e24\u79cd\u89e3\u51b3 C10K\/C10M \u95ee\u9898\u7684\u5dc5\u5cf0\u601d\u8def\u3002\u5c06\u4e24\u8005\u8fdb\u884c\u5bf9\u6bd4&#xff0c;\u80fd\u8ba9\u6211\u4eec\u66f4\u6df1\u523b\u5730\u7406\u89e3 Redis 8.4 \u4e3a\u4ec0\u4e48\u8981\u575a\u6301\u201c\u602a\u5f02\u201d\u7684\u5355\u7ebf\u7a0b\u6267\u884c\u6a21\u578b\u3002<\/p>\n<h3>10.1 \u6838\u5fc3\u67b6\u6784\u56fe\u89e3&#xff1a;\u7c73\u5176\u6797\u9910\u5385 vs \u5916\u5356\u5e73\u53f0<\/h3>\n<p>\u4e3a\u4e86\u76f4\u89c2\u7406\u89e3\u4e24\u8005\u7684\u5dee\u5f02&#xff0c;\u6211\u4eec\u901a\u8fc7\u4e00\u5f20\u67b6\u6784\u5bf9\u6bd4\u56fe\u6765\u5c55\u793a\u5b83\u4eec\u5728 \u8c03\u5ea6\u7b56\u7565 \u548c \u6267\u884c\u5e76\u53d1\u6027 \u4e0a\u7684\u6839\u672c\u4e0d\u540c\u3002<\/p>\n<p>  #mermaid-svg-3PBZI5efHWeK3pza{font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3PBZI5efHWeK3pza .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3PBZI5efHWeK3pza .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3PBZI5efHWeK3pza .error-icon{fill:#552222;}#mermaid-svg-3PBZI5efHWeK3pza .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3PBZI5efHWeK3pza .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3PBZI5efHWeK3pza .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3PBZI5efHWeK3pza .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3PBZI5efHWeK3pza .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3PBZI5efHWeK3pza .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3PBZI5efHWeK3pza .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3PBZI5efHWeK3pza .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3PBZI5efHWeK3pza .marker.cross{stroke:#333333;}#mermaid-svg-3PBZI5efHWeK3pza svg{font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3PBZI5efHWeK3pza p{margin:0;}#mermaid-svg-3PBZI5efHWeK3pza .label{font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;color:#333;}#mermaid-svg-3PBZI5efHWeK3pza .cluster-label text{fill:#333;}#mermaid-svg-3PBZI5efHWeK3pza .cluster-label span{color:#333;}#mermaid-svg-3PBZI5efHWeK3pza .cluster-label span p{background-color:transparent;}#mermaid-svg-3PBZI5efHWeK3pza .label text,#mermaid-svg-3PBZI5efHWeK3pza span{fill:#333;color:#333;}#mermaid-svg-3PBZI5efHWeK3pza .node rect,#mermaid-svg-3PBZI5efHWeK3pza .node circle,#mermaid-svg-3PBZI5efHWeK3pza .node ellipse,#mermaid-svg-3PBZI5efHWeK3pza .node polygon,#mermaid-svg-3PBZI5efHWeK3pza .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3PBZI5efHWeK3pza .rough-node .label text,#mermaid-svg-3PBZI5efHWeK3pza .node .label text,#mermaid-svg-3PBZI5efHWeK3pza .image-shape .label,#mermaid-svg-3PBZI5efHWeK3pza .icon-shape .label{text-anchor:middle;}#mermaid-svg-3PBZI5efHWeK3pza .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3PBZI5efHWeK3pza .rough-node .label,#mermaid-svg-3PBZI5efHWeK3pza .node .label,#mermaid-svg-3PBZI5efHWeK3pza .image-shape .label,#mermaid-svg-3PBZI5efHWeK3pza .icon-shape .label{text-align:center;}#mermaid-svg-3PBZI5efHWeK3pza .node.clickable{cursor:pointer;}#mermaid-svg-3PBZI5efHWeK3pza .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3PBZI5efHWeK3pza .arrowheadPath{fill:#333333;}#mermaid-svg-3PBZI5efHWeK3pza .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3PBZI5efHWeK3pza .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3PBZI5efHWeK3pza .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3PBZI5efHWeK3pza .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3PBZI5efHWeK3pza .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3PBZI5efHWeK3pza .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3PBZI5efHWeK3pza .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3PBZI5efHWeK3pza .cluster text{fill:#333;}#mermaid-svg-3PBZI5efHWeK3pza .cluster span{color:#333;}#mermaid-svg-3PBZI5efHWeK3pza div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3PBZI5efHWeK3pza .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3PBZI5efHWeK3pza rect.text{fill:none;stroke-width:0;}#mermaid-svg-3PBZI5efHWeK3pza .icon-shape,#mermaid-svg-3PBZI5efHWeK3pza .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3PBZI5efHWeK3pza .icon-shape p,#mermaid-svg-3PBZI5efHWeK3pza .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3PBZI5efHWeK3pza .icon-shape rect,#mermaid-svg-3PBZI5efHWeK3pza .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3PBZI5efHWeK3pza .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3PBZI5efHWeK3pza .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3PBZI5efHWeK3pza :root{&#8211;mermaid-font-family:\\&#8221;trebuchet ms\\&#8221;,verdana,arial,sans-serif;}#mermaid-svg-3PBZI5efHWeK3pza .redisFill&gt;*{fill:#fff3e0!important;stroke:#e65100!important;stroke-width:2px!important;}#mermaid-svg-3PBZI5efHWeK3pza .redisFill span{fill:#fff3e0!important;stroke:#e65100!important;stroke-width:2px!important;}#mermaid-svg-3PBZI5efHWeK3pza .goFill&gt;*{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;}#mermaid-svg-3PBZI5efHWeK3pza .goFill span{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;}#mermaid-svg-3PBZI5efHWeK3pza .component&gt;*{fill:#ffffff!important;stroke:#333!important;stroke-dasharray:5 5!important;}#mermaid-svg-3PBZI5efHWeK3pza .component span{fill:#ffffff!important;stroke:#333!important;stroke-dasharray:5 5!important;} <\/p>\n<p>           <span class=\"nodeLabel\"><\/p>\n<p>Go Netpoller (\u5916\u5356\u5e73\u53f0\u6a21\u5f0f)<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"edgeLabel\"><\/span> <\/p>\n<p>           <span class=\"edgeLabel\"><\/span> <\/p>\n<p>           <span class=\"edgeLabel\"><\/p>\n<p>\u5c31\u7eea\u4e8b\u4ef6<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"edgeLabel\"><\/p>\n<p>\u62a2\u5360\/\u7a83\u53d6<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"edgeLabel\"><\/p>\n<p>\u62a2\u5360\/\u7a83\u53d6<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"edgeLabel\"><\/p>\n<p>\u62a2\u5360\/\u7a83\u53d6<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"nodeLabel\"><\/p>\n<p>Conn A<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"nodeLabel\"><\/p>\n<p>Netpoller (Epoll)<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"nodeLabel\"><\/p>\n<p>Conn B<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"nodeLabel\"><\/p>\n<p>Global \/ Local RunQueue<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"nodeLabel\"><\/p>\n<p>P1 &#043; M1<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"nodeLabel\"><\/p>\n<p>P2 &#043; M2<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"nodeLabel\"><\/p>\n<p>P3 &#043; M3<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"nodeLabel\"><\/p>\n<p>\u7279\u70b9: 1. IO \u5e76\u884c, \u903b\u8f91\u5e76\u884c2. \u52a8\u6001\u8c03\u5ea6 (Work Stealing)3. \u9700\u8981\u7528\u6237\u52a0\u9501 (Mutex)<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"nodeLabel\"><\/p>\n<p>Redis 8.4 (\u7c73\u5176\u6797\u9910\u5385\u6a21\u5f0f)<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"edgeLabel\"><\/p>\n<p>\u56fa\u5b9a\u7ed1\u5b9a<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"edgeLabel\"><\/p>\n<p>\u56fa\u5b9a\u7ed1\u5b9a<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"edgeLabel\"><\/p>\n<p>\u56fa\u5b9a\u7ed1\u5b9a<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"edgeLabel\"><\/p>\n<p>\u89e3\u6790\u5b8c\u7684\u547d\u4ee4<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"edgeLabel\"><\/p>\n<p>\u89e3\u6790\u5b8c\u7684\u547d\u4ee4<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"edgeLabel\"><\/span> <\/p>\n<p>           <span class=\"nodeLabel\"><\/p>\n<p>Client A<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"nodeLabel\"><\/p>\n<p>IO Thread 1<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"nodeLabel\"><\/p>\n<p>Client B<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"nodeLabel\"><\/p>\n<p>Client C<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"nodeLabel\"><\/p>\n<p>IO Thread 2<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"nodeLabel\"><\/p>\n<p>\u65e0\u9501\u4ea4\u6362\u961f\u5217<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"nodeLabel\"><\/p>\n<p>Main Thread (\u53a8\u5e08\u957f)<\/p>\n<p><\/span> <\/p>\n<p>           <span class=\"nodeLabel\"><\/p>\n<p>\u7279\u70b9: 1. IO \u5e76\u884c, \u903b\u8f91\u4e32\u884c2. \u9759\u6001\u7ed1\u5b9a (Affinity \u6781\u9ad8)3. \u65e0\u9501\u6267\u884c (No Race)<\/p>\n<p><\/span> <\/p>\n<h3>10.2 \u6838\u5fc3\u5dee\u5f02\u6df1\u5ea6\u89e3\u6790<\/h3>\n<h4>10.2.1. \u903b\u8f91\u6267\u884c\u7684\u5e76\u53d1\u6027&#xff08;Serial vs Parallel&#xff09;<\/h4>\n<ul>\n<li>Redis 8.4 (IO \u5e76\u884c&#xff0c;\u903b\u8f91\u4e32\u884c)&#xff1a;\n<ul>\n<li>\u673a\u5236&#xff1a;\u6240\u6709 IO \u7ebf\u7a0b\u5c06\u89e3\u6790\u597d\u7684\u547d\u4ee4\u6c47\u805a\u7ed9\u4e3b\u7ebf\u7a0b&#xff0c;\u4e3b\u7ebf\u7a0b\u6392\u961f\u6267\u884c\u3002<\/li>\n<li>\u76ee\u7684&#xff1a;Redis \u62e5\u6709 Hash, ZSet \u7b49\u590d\u6742\u6570\u636e\u7ed3\u6784\u3002\u5982\u679c\u903b\u8f91\u5e76\u884c&#xff0c;\u5fc5\u987b\u5f15\u5165\u7ec6\u7c92\u5ea6\u7684\u884c\u7ea7\u9501&#xff08;Row-level Lock&#xff09;\u3002\u5728\u9ad8\u9891\u64cd\u4f5c\u4e0b&#xff0c;\u9501\u7ade\u4e89\u7684\u5f00\u9500\u4f1a\u5b8c\u5168\u62b5\u6d88\u591a\u6838\u7684\u6536\u76ca\u3002<\/li>\n<li>\u6536\u76ca&#xff1a;\u5f00\u53d1\u8005\u4eab\u53d7\u4e86\u201c\u65e0\u9501\u7f16\u7a0b\u201d\u7684\u7ea2\u5229&#xff0c;\u539f\u5b50\u6027\u5929\u7136\u4fdd\u8bc1&#xff0c;\u4ee3\u7801\u6781\u5ea6\u7b80\u5355\u4e14\u9ad8\u6548\u3002<\/li>\n<\/ul>\n<\/li>\n<li>Go (\u5168\u5e76\u884c)&#xff1a;\n<ul>\n<li>\u673a\u5236&#xff1a;\u4efb\u610f Goroutine \u53ef\u80fd\u5728\u4efb\u610f P&#xff08;CPU \u6838&#xff09;\u4e0a\u8fd0\u884c&#xff0c;\u4e1a\u52a1\u903b\u8f91\u5929\u7136\u5e76\u884c\u3002<\/li>\n<li>\u4ee3\u4ef7&#xff1a;\u5f53\u591a\u4e2a Goroutine \u64cd\u4f5c\u5171\u4eab\u8d44\u6e90&#xff08;\u5982\u5168\u5c40 Map&#xff09;\u65f6&#xff0c;\u5f00\u53d1\u8005\u5fc5\u987b\u663e\u5f0f\u4f7f\u7528 sync.Mutex \u6216 Channel\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h4>10.2.2. \u8c03\u5ea6\u54f2\u5b66&#xff1a;\u9759\u6001\u7ed1\u5b9a vs \u5de5\u4f5c\u7a83\u53d6<\/h4>\n<ul>\n<li>Redis (Static Binding)&#xff1a;\n<ul>\n<li>\u7b56\u7565&#xff1a;assignClientToIOThread\u3002\u4e00\u4e2a\u8fde\u63a5\u4e00\u65e6\u5206\u914d\u7ed9 3 \u53f7\u7ebf\u7a0b&#xff0c;\u9664\u975e\u65ad\u5f00&#xff0c;\u5426\u5219\u6c38\u8fdc\u7531 3 \u53f7\u7ebf\u7a0b\u8d1f\u8d23\u3002<\/li>\n<li>\u4f18\u52bf&#xff1a;\u6781\u81f4\u7684 CPU \u4eb2\u548c\u6027 (CPU Affinity) \u548c L1\/L2 Cache \u547d\u4e2d\u7387\u3002Redis \u662f\u5185\u5b58\u6570\u636e\u5e93&#xff0c;Cache Miss \u662f\u6700\u5927\u7684\u6027\u80fd\u6740\u624b\u3002\u8fd9\u79cd\u8bbe\u8ba1\u4fdd\u8bc1\u4e86\u8fde\u63a5\u7684\u4e0a\u4e0b\u6587\u59cb\u7ec8\u70ed\u5b58\u5728\u4e8e\u67d0\u4e2a CPU \u6838\u5fc3\u7684\u7f13\u5b58\u4e2d\u3002<\/li>\n<\/ul>\n<\/li>\n<li>Go (Work Stealing)&#xff1a;\n<ul>\n<li>\u7b56\u7565&#xff1a;\u5982\u679c P1 \u95f2\u4e86\u800c P2 \u5fd9&#xff0c;P1 \u4f1a\u4ece P2 \u7684\u961f\u5217\u91cc\u201c\u5077\u201d\u4efb\u52a1&#xff08;G&#xff09;\u6765\u8dd1\u3002<\/li>\n<li>\u4f18\u52bf&#xff1a;\u6700\u5927\u5316 CPU \u541e\u5410\u91cf\u3002\u4fdd\u8bc1\u6ca1\u6709 CPU \u6838\u5fc3\u5728\u5077\u61d2\u3002<\/li>\n<li>\u52a3\u52bf&#xff1a;Goroutine \u53ef\u80fd\u5728\u4e0d\u540c CPU \u6838\u4e4b\u95f4\u6f02\u79fb&#xff0c;\u5bfc\u81f4\u7f13\u5b58\u5931\u6548&#xff08;Cache Thrashing&#xff09;\u3002\u5bf9\u4e8e\u901a\u7528\u4e1a\u52a1\u8fd9\u6ca1\u95ee\u9898&#xff0c;\u4f46\u5bf9\u4e8e Redis \u8fd9\u79cd\u5fae\u79d2\u7ea7\u5ef6\u8fdf\u654f\u611f\u7684\u5e94\u7528\u662f\u4e0d\u53ef\u63a5\u53d7\u7684\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>10.3 \u7ec8\u6781\u8ffd\u95ee&#xff1a;\u4e3a\u4ec0\u4e48 Redis \u4e0d\u7528 Go \u91cd\u5199&#xff1f;<\/h3>\n<p>\u5982\u679c\u7528 Go \u91cd\u5199 Redis&#xff0c;\u7406\u8bba\u4e0a\u7f51\u7edc\u5c42\u4ee3\u7801\u4f1a\u51cf\u5c11 90%&#xff0c;\u4f46\u4f1a\u9762\u4e34\u4e09\u4e2a\u65e0\u6cd5\u903e\u8d8a\u7684\u969c\u788d&#xff1a;<\/p>\n<li>GC \u7684\u201c\u505c\u987f\u4e4b\u6b87\u201d&#xff1a; Redis \u7ecf\u5e38\u627f\u8f7d\u51e0\u5341 GB \u7684\u6570\u636e\u3002Go \u7684 GC \u867d\u7136\u5728\u4f18\u5316&#xff0c;\u4f46\u5728\u626b\u63cf\u5de8\u5927\u5806\u5185\u5b58\u65f6\u4ea7\u751f\u7684 STW&#xff08;\u6216\u5199\u5c4f\u969c\u5e26\u6765\u7684\u541e\u5410\u4e0b\u964d&#xff09;&#xff0c;\u5bf9\u4e8e\u8981\u6c42 99.9% \u54cd\u5e94\u5728 1ms \u4ee5\u5185 \u7684\u7f13\u5b58\u670d\u52a1\u6765\u8bf4\u662f\u81f4\u547d\u7684\u3002<\/li>\n<li>\u5185\u5b58\u5e03\u5c40\u7684\u201c\u9ed1\u76d2\u201d&#xff1a; C \u8bed\u8a00\u5141\u8bb8 Redis \u624b\u52a8\u63a7\u5236\u5185\u5b58\u5e03\u5c40&#xff08;\u5982 SDS \u7684\u7d27\u51d1\u5185\u5b58\u3001Ziplist \u7684\u8fde\u7eed\u5185\u5b58&#xff09;&#xff0c;\u4ee5\u5229\u7528 CPU Cache Line\u3002Go \u7684\u5185\u5b58\u7531 Runtime \u6258\u7ba1&#xff0c;\u65e0\u6cd5\u505a\u5230\u5982\u6b64\u6781\u81f4\u7684\u5fae\u8c03\u3002<\/li>\n<li>\u9501\u7684\u201c\u5e76\u53d1\u9677\u9631\u201d&#xff1a; Go \u7684\u9ad8\u5e76\u53d1\u6a21\u578b\u9700\u8981\u9501\u6765\u4fdd\u62a4\u5168\u5c40\u72b6\u6001\u3002\u5728 Redis \u7684\u573a\u666f\u4e0b&#xff08;\u5168\u662f\u5168\u5c40\u72b6\u6001&#xff09;&#xff0c;\u9501\u7684\u5f00\u9500 &gt; \u5355\u7ebf\u7a0b\u987a\u5e8f\u6267\u884c\u7684\u5f00\u9500\u3002<\/li>\n<p>\u603b\u7ed3&#xff1a; Redis 8.4 \u7684\u7f51\u7edc\u6a21\u578b&#xff0c;\u662f\u5728 C \u8bed\u8a00\u6ca1\u6709 Goroutine \u8fd9\u79cd\u201c\u9ed1\u79d1\u6280\u201d\u7684\u524d\u63d0\u4e0b&#xff0c;\u901a\u8fc7\u6781\u81f4\u7684\u5de5\u7a0b\u8bbe\u8ba1&#xff0c;\u624b\u52a8\u5b9e\u73b0\u4e86\u4e00\u5957\u201c\u4e13\u7528\u7684\u3001\u9759\u6001\u7ed1\u5b9a\u7684\u3001\u9488\u5bf9\u7279\u5b9a\u573a\u666f&#xff08;\u5185\u5b58\u64cd\u4f5c&#xff09;\u4f18\u5316\u7684\u201d GMP \u6a21\u578b\u3002\u5b83\u662f\u7279\u79cd\u90e8\u961f&#xff0c;\u800c Go \u7684 Netpoller \u662f\u901a\u7528\u96c6\u56e2\u519b\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u7b2c\u4e00\u90e8\u5206&#xff1a;Redis 8.4 \u7f51\u7edc\u6a21\u578b\u5b8f\u89c2\u67b6\u6784\u4e0e\u6e90\u7801\u5165\u53e3<br \/>\n\u5e74\u524d\u8fd9\u6bb5\u65f6\u95f4\u8d4b\u95f2\u5728\u5bb6&#xff0c;\u6211\u7cfb\u7edf\u6574\u7406\u4e86 10 \u7bc7\u6df1\u5ea6\u89e3\u6790 Go \u8bed\u8a00\u7684\u786c\u6838\u6587\u7ae0&#xff0c;\u968f\u540e\u53c8\u7cbe\u9009\u4e86 10 \u7bc7\u5f53\u4e0b\u70ed\u95e8 AI \u5927\u6a21\u578b\u7684\u6280\u672f\u6587\u7ae0&#xff08;Token\u3001MCP\u3001Agent\u3001Skills\u3001Vibe Coding \u7b49&#xff09;\u3002\u4eca\u5929&#xff0c;\u6211\u5c06\u89c6\u89d2\u8f6c\u5411 Redis&#xff0c;\u4ece\u6e90\u7801\u5c42\u9762\u6df1\u5165\u5256\u6790\u5b83\u7684\u7f51\u7edc\u6a21\u578b\u5b9e\u73b0&#xff0c;\u82e5\u5bf9 Redis \u6570\u636e\u7ed3\u6784\u611f\u5174\u8da3<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[105,188,78],"topic":[],"class_list":["post-65929","post","type-post","status-publish","format-standard","hentry","category-server","tag-redis","tag-188","tag-78"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u4e07\u5b57\u957f\u6587\u89e3\u6790\uff1aRedis 8.4 \u7f51\u7edc IO \u67b6\u6784\u6df1\u5ea6\u62c6\u89e3 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.wsisp.com\/helps\/65929.html\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u4e07\u5b57\u957f\u6587\u89e3\u6790\uff1aRedis 8.4 \u7f51\u7edc IO \u67b6\u6784\u6df1\u5ea6\u62c6\u89e3 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"og:description\" content=\"\u7b2c\u4e00\u90e8\u5206&#xff1a;Redis 8.4 \u7f51\u7edc\u6a21\u578b\u5b8f\u89c2\u67b6\u6784\u4e0e\u6e90\u7801\u5165\u53e3 \u5e74\u524d\u8fd9\u6bb5\u65f6\u95f4\u8d4b\u95f2\u5728\u5bb6&#xff0c;\u6211\u7cfb\u7edf\u6574\u7406\u4e86 10 \u7bc7\u6df1\u5ea6\u89e3\u6790 Go \u8bed\u8a00\u7684\u786c\u6838\u6587\u7ae0&#xff0c;\u968f\u540e\u53c8\u7cbe\u9009\u4e86 10 \u7bc7\u5f53\u4e0b\u70ed\u95e8 AI \u5927\u6a21\u578b\u7684\u6280\u672f\u6587\u7ae0&#xff08;Token\u3001MCP\u3001Agent\u3001Skills\u3001Vibe Coding \u7b49&#xff09;\u3002\u4eca\u5929&#xff0c;\u6211\u5c06\u89c6\u89d2\u8f6c\u5411 Redis&#xff0c;\u4ece\u6e90\u7801\u5c42\u9762\u6df1\u5165\u5256\u6790\u5b83\u7684\u7f51\u7edc\u6a21\u578b\u5b9e\u73b0&#xff0c;\u82e5\u5bf9 Redis \u6570\u636e\u7ed3\u6784\u611f\u5174\u8da3\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.wsisp.com\/helps\/65929.html\" \/>\n<meta property=\"og:site_name\" content=\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"article:published_time\" content=\"2026-01-25T14:16:55+00:00\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"43 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/65929.html\",\"url\":\"https:\/\/www.wsisp.com\/helps\/65929.html\",\"name\":\"\u4e07\u5b57\u957f\u6587\u89e3\u6790\uff1aRedis 8.4 \u7f51\u7edc IO \u67b6\u6784\u6df1\u5ea6\u62c6\u89e3 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"isPartOf\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\"},\"datePublished\":\"2026-01-25T14:16:55+00:00\",\"dateModified\":\"2026-01-25T14:16:55+00:00\",\"author\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/65929.html#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.wsisp.com\/helps\/65929.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/65929.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.wsisp.com\/helps\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u4e07\u5b57\u957f\u6587\u89e3\u6790\uff1aRedis 8.4 \u7f51\u7edc IO \u67b6\u6784\u6df1\u5ea6\u62c6\u89e3\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\",\"url\":\"https:\/\/www.wsisp.com\/helps\/\",\"name\":\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"description\":\"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"contentUrl\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"caption\":\"admin\"},\"sameAs\":[\"http:\/\/wp.wsisp.com\"],\"url\":\"https:\/\/www.wsisp.com\/helps\/author\/admin\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"\u4e07\u5b57\u957f\u6587\u89e3\u6790\uff1aRedis 8.4 \u7f51\u7edc IO \u67b6\u6784\u6df1\u5ea6\u62c6\u89e3 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.wsisp.com\/helps\/65929.html","og_locale":"zh_CN","og_type":"article","og_title":"\u4e07\u5b57\u957f\u6587\u89e3\u6790\uff1aRedis 8.4 \u7f51\u7edc IO \u67b6\u6784\u6df1\u5ea6\u62c6\u89e3 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","og_description":"\u7b2c\u4e00\u90e8\u5206&#xff1a;Redis 8.4 \u7f51\u7edc\u6a21\u578b\u5b8f\u89c2\u67b6\u6784\u4e0e\u6e90\u7801\u5165\u53e3 \u5e74\u524d\u8fd9\u6bb5\u65f6\u95f4\u8d4b\u95f2\u5728\u5bb6&#xff0c;\u6211\u7cfb\u7edf\u6574\u7406\u4e86 10 \u7bc7\u6df1\u5ea6\u89e3\u6790 Go \u8bed\u8a00\u7684\u786c\u6838\u6587\u7ae0&#xff0c;\u968f\u540e\u53c8\u7cbe\u9009\u4e86 10 \u7bc7\u5f53\u4e0b\u70ed\u95e8 AI \u5927\u6a21\u578b\u7684\u6280\u672f\u6587\u7ae0&#xff08;Token\u3001MCP\u3001Agent\u3001Skills\u3001Vibe Coding \u7b49&#xff09;\u3002\u4eca\u5929&#xff0c;\u6211\u5c06\u89c6\u89d2\u8f6c\u5411 Redis&#xff0c;\u4ece\u6e90\u7801\u5c42\u9762\u6df1\u5165\u5256\u6790\u5b83\u7684\u7f51\u7edc\u6a21\u578b\u5b9e\u73b0&#xff0c;\u82e5\u5bf9 Redis \u6570\u636e\u7ed3\u6784\u611f\u5174\u8da3","og_url":"https:\/\/www.wsisp.com\/helps\/65929.html","og_site_name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","article_published_time":"2026-01-25T14:16:55+00:00","author":"admin","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"admin","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"43 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.wsisp.com\/helps\/65929.html","url":"https:\/\/www.wsisp.com\/helps\/65929.html","name":"\u4e07\u5b57\u957f\u6587\u89e3\u6790\uff1aRedis 8.4 \u7f51\u7edc IO \u67b6\u6784\u6df1\u5ea6\u62c6\u89e3 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","isPartOf":{"@id":"https:\/\/www.wsisp.com\/helps\/#website"},"datePublished":"2026-01-25T14:16:55+00:00","dateModified":"2026-01-25T14:16:55+00:00","author":{"@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41"},"breadcrumb":{"@id":"https:\/\/www.wsisp.com\/helps\/65929.html#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.wsisp.com\/helps\/65929.html"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.wsisp.com\/helps\/65929.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.wsisp.com\/helps"},{"@type":"ListItem","position":2,"name":"\u4e07\u5b57\u957f\u6587\u89e3\u6790\uff1aRedis 8.4 \u7f51\u7edc IO \u67b6\u6784\u6df1\u5ea6\u62c6\u89e3"}]},{"@type":"WebSite","@id":"https:\/\/www.wsisp.com\/helps\/#website","url":"https:\/\/www.wsisp.com\/helps\/","name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","description":"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41","name":"admin","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/","url":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","contentUrl":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","caption":"admin"},"sameAs":["http:\/\/wp.wsisp.com"],"url":"https:\/\/www.wsisp.com\/helps\/author\/admin"}]}},"_links":{"self":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/65929","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/comments?post=65929"}],"version-history":[{"count":0,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/65929\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media?parent=65929"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/categories?post=65929"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/tags?post=65929"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/topic?post=65929"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}