valkey之網絡管理架構深度解析

一、連接類型實現體系

valkey通過ConnectionType結構體構建了靈活的網絡連接抽象,支持多種連接類型的統一管理。每種連接類型都通過填充該結構體的函數指針來實現特定功能,形成了面向接口的設計模式。

在這里插入圖片描述

1.1 socket連接

Socket連接提供了最基礎的TCP/IP通信能力,實現了全部連接與IO操作接口,是valkey網絡通信的基礎實現。

src/socket.c

static ConnectionType CT_Socket = {/* connection type */.get_type = connSocketGetType,/* connection type initialize & finalize & configure */.init = NULL,.cleanup = NULL,.configure = NULL,/* ae & accept & listen & error & address handler */.ae_handler = connSocketEventHandler,.accept_handler = connSocketAcceptHandler,.addr = connSocketAddr,.is_local = connSocketIsLocal,.listen = connSocketListen,.closeListener = connSocketCloseListener,/* create/shutdown/close connection */.conn_create = connCreateSocket,.conn_create_accepted = connCreateAcceptedSocket,.shutdown = connSocketShutdown,.close = connSocketClose,/* connect & accept */.connect = connSocketConnect,.blocking_connect = connSocketBlockingConnect,.accept = connSocketAccept,/* IO */.write = connSocketWrite,.writev = connSocketWritev,.read = connSocketRead,.set_write_handler = connSocketSetWriteHandler,.set_read_handler = connSocketSetReadHandler,.get_last_error = connSocketGetLastError,.sync_write = connSocketSyncWrite,.sync_read = connSocketSyncRead,.sync_readline = connSocketSyncReadLine,/* pending data */.has_pending_data = NULL,.process_pending_data = NULL,.postpone_update_state = NULL,.update_state = NULL,/* Miscellaneous */.connIntegrityChecked = NULL,
};int RedisRegisterConnectionTypeSocket(void) {return connTypeRegister(&CT_Socket);
}

1.2 unix域套接字

Unix域套接字專注于本地進程間通信,省略了網絡連接相關的接口,優化了本地通信的性能。

src/unix.c

static ConnectionType CT_Unix = {/* connection type */.get_type = connUnixGetType,/* connection type initialize & finalize & configure */.init = NULL,.cleanup = NULL,.configure = NULL,/* ae & accept & listen & error & address handler */.ae_handler = connUnixEventHandler,.accept_handler = connUnixAcceptHandler,.addr = connUnixAddr,.is_local = connUnixIsLocal,.listen = connUnixListen,.closeListener = connUnixCloseListener,/* create/shutdown/close connection */.conn_create = connCreateUnix,.conn_create_accepted = connCreateAcceptedUnix,.shutdown = connUnixShutdown,.close = connUnixClose,/* connect & accept */.connect = NULL,.blocking_connect = NULL,.accept = connUnixAccept,/* IO */.write = connUnixWrite,.writev = connUnixWritev,.read = connUnixRead,.set_write_handler = connUnixSetWriteHandler,.set_read_handler = connUnixSetReadHandler,.get_last_error = connUnixGetLastError,.sync_write = connUnixSyncWrite,.sync_read = connUnixSyncRead,.sync_readline = connUnixSyncReadLine,/* pending data */.has_pending_data = NULL,.process_pending_data = NULL,.postpone_update_state = NULL,.update_state = NULL,/* Miscellaneous */.connIntegrityChecked = NULL,
};int RedisRegisterConnectionTypeUnix(void) {return connTypeRegister(&CT_Unix);
}

1.3 tls加密連接

TLS連接增加了加密相關的初始化、清理和配置接口,提供了證書處理和加密數據傳輸能力,是安全通信的實現。

src/tls.c

static ConnectionType CT_TLS = {/* connection type */.get_type = connTLSGetType,/* connection type initialize & finalize & configure */.init = tlsInit,.cleanup = tlsCleanup,.configure = tlsConfigure,/* ae & accept & listen & error & address handler */.ae_handler = tlsEventHandler,.accept_handler = tlsAcceptHandler,.addr = connTLSAddr,.is_local = connTLSIsLocal,.listen = connTLSListen,.closeListener = connTLSCloseListener,/* create/shutdown/close connection */.conn_create = connCreateTLS,.conn_create_accepted = connCreateAcceptedTLS,.shutdown = connTLSShutdown,.close = connTLSClose,/* connect & accept */.connect = connTLSConnect,.blocking_connect = connTLSBlockingConnect,.accept = connTLSAccept,/* IO */.read = connTLSRead,.write = connTLSWrite,.writev = connTLSWritev,.set_write_handler = connTLSSetWriteHandler,.set_read_handler = connTLSSetReadHandler,.get_last_error = connTLSGetLastError,.sync_write = connTLSSyncWrite,.sync_read = connTLSSyncRead,.sync_readline = connTLSSyncReadLine,/* pending data */.has_pending_data = tlsHasPendingData,.process_pending_data = tlsProcessPendingData,.postpone_update_state = postPoneUpdateSSLState,.update_state = updateSSLState,/* TLS specified methods */.get_peer_cert = connTLSGetPeerCert,/* Miscellaneous */.connIntegrityChecked = connTLSIsIntegrityChecked,
};int RedisRegisterConnectionTypeTLS(void) {return connTypeRegister(&CT_TLS);
}

1.4 rdma高性能連接

RDMA連接針對高性能計算場景設計,提供了低延遲的數據傳輸能力,包含了特殊的狀態管理接口。

src/rdma.c

static ConnectionType CT_RDMA = {/* connection type */.get_type = connRdmaGetType,/* connection type initialize & finalize & configure */.init = rdmaInit,.cleanup = NULL,/* ae & accept & listen & error & address handler */.ae_handler = connRdmaEventHandler,.accept_handler = connRdmaAcceptHandler,//.cluster_accept_handler = NULL,.is_local = connRdmaIsLocal,.listen = connRdmaListen,.closeListener = connRdmaCloseListener,.addr = connRdmaAddr,/* create/close connection */.conn_create = connCreateRdma,.conn_create_accepted = connCreateAcceptedRdma,.shutdown = connRdmaShutdown,.close = connRdmaClose,/* connect & accept */.connect = connRdmaConnect,.blocking_connect = connRdmaBlockingConnect,.accept = connRdmaAccept,/* IO */.write = connRdmaWrite,.writev = connRdmaWritev,.read = connRdmaRead,.set_write_handler = connRdmaSetWriteHandler,.set_read_handler = connRdmaSetReadHandler,.get_last_error = connRdmaGetLastError,.sync_write = connRdmaSyncWrite,.sync_read = connRdmaSyncRead,.sync_readline = connRdmaSyncReadLine,/* pending data */.has_pending_data = rdmaHasPendingData,.process_pending_data = rdmaProcessPendingData,.postpone_update_state = postPoneUpdateRdmaState,.update_state = updateRdmaState,/* Miscellaneous */.connIntegrityChecked = NULL,
};int RegisterConnectionTypeRdma(void) {return connTypeRegister(&CT_RDMA);
}

二、連接類型注冊流程

2.1 注冊調用鏈

src/server.c
main|   src/connection.c|--> connTypeInitialize

2.2 注冊實現

src/connection.c

int connTypeInitialize(void) {/* currently socket connection type is necessary  */serverAssert(RedisRegisterConnectionTypeSocket() == C_OK);/* currently unix socket connection type is necessary  */serverAssert(RedisRegisterConnectionTypeUnix() == C_OK);/* may fail if without BUILD_TLS=yes */RedisRegisterConnectionTypeTLS();/* may fail if without BUILD_RDMA=yes */RegisterConnectionTypeRdma();return C_OK;
}

這種注冊機制實現了:?

  • 核心連接類型的強制注冊(Socket和Unix)?
  • 可選連接類型的條件注冊(TLS和RDMA)?
  • 編譯時決定是否支持特定連接類型的靈活性

三、監聽器初始化流程

監聽器初始化是valkey網絡服務啟動的關鍵步驟,負責根據配置創建并激活各類連接的監聽機制。

3.1 初始化調用鏈

src/server.c
main|   src/config.c|--> loadServerConfig||    src/server.c|--> initListeners

3.2 初始化實現

根據不同的配置,初始化不同的監聽器。

void initListeners(void) {/* Setup listeners from server config for TCP/TLS/Unix */int conn_index;connListener *listener;if (server.port != 0) {conn_index = connectionIndexByType(CONN_TYPE_SOCKET);if (conn_index < 0) serverPanic("Failed finding connection listener of %s", CONN_TYPE_SOCKET);listener = &server.listeners[conn_index];listener->bindaddr = server.bindaddr;listener->bindaddr_count = server.bindaddr_count;listener->port = server.port;listener->ct = connectionByType(CONN_TYPE_SOCKET);}if (server.tls_port || server.tls_replication || server.tls_cluster) {ConnectionType *ct_tls = connectionTypeTls();if (!ct_tls) {serverLog(LL_WARNING, "Failed finding TLS support.");exit(1);}if (connTypeConfigure(ct_tls, &server.tls_ctx_config, 1) == C_ERR) {serverLog(LL_WARNING, "Failed to configure TLS. Check logs for more info.");exit(1);}}if (server.tls_port != 0) {conn_index = connectionIndexByType(CONN_TYPE_TLS);if (conn_index < 0) serverPanic("Failed finding connection listener of %s", CONN_TYPE_TLS);listener = &server.listeners[conn_index];listener->bindaddr = server.bindaddr;listener->bindaddr_count = server.bindaddr_count;listener->port = server.tls_port;listener->ct = connectionByType(CONN_TYPE_TLS);}if (server.unixsocket != NULL) {conn_index = connectionIndexByType(CONN_TYPE_UNIX);if (conn_index < 0) serverPanic("Failed finding connection listener of %s", CONN_TYPE_UNIX);listener = &server.listeners[conn_index];listener->bindaddr = &server.unixsocket;listener->bindaddr_count = 1;listener->ct = connectionByType(CONN_TYPE_UNIX);listener->priv = &server.unix_ctx_config; /* Unix socket specified */}if (server.rdma_ctx_config.port != 0) {conn_index = connectionIndexByType(CONN_TYPE_RDMA);if (conn_index < 0) serverPanic("Failed finding connection listener of %s", CONN_TYPE_RDMA);listener = &server.listeners[conn_index];listener->bindaddr = server.rdma_ctx_config.bindaddr;listener->bindaddr_count = server.rdma_ctx_config.bindaddr_count;listener->port = server.rdma_ctx_config.port;listener->ct = connectionByType(CONN_TYPE_RDMA);listener->priv = &server.rdma_ctx_config;}/* create all the configured listener, and add handler to start to accept */int listen_fds = 0;for (int j = 0; j < CONN_TYPE_MAX; j++) {listener = &server.listeners[j];if (listener->ct == NULL) continue;if (connListen(listener) == C_ERR) {serverLog(LL_WARNING, "Failed listening on port %u (%s), aborting.", listener->port,listener->ct->get_type(NULL));exit(1);}if (createSocketAcceptHandler(listener, connAcceptHandler(listener->ct)) != C_OK)serverPanic("Unrecoverable error creating %s listener accept handler.", listener->ct->get_type(NULL));listen_fds += listener->count;}if (listen_fds == 0) {serverLog(LL_WARNING, "Configured to not listen anywhere, exiting.");exit(1);}
}

四、抽象連接層設計

valkey通過connection.h頭文件定義了抽象連接層的接口,實現了對各類連接的統一操作,體現了面向對象的多態特性。

4.1 統一接口設計

src/connection.h

...static inline int connWritev(connection *conn, const struct iovec *iov, int iovcnt) {return conn->type->writev(conn, iov, iovcnt);
}static inline int connRead(connection *conn, void *buf, size_t buf_len) {int ret = conn->type->read(conn, buf, buf_len);return ret;
}...

4.2 多態實現機制

抽象連接層通過函數指針實現了多態:?

  • 上層代碼使用統一的connReadconnWritev等接口?
  • 實際執行時根據conn->type指向的具體連接類型,調用對應的實現函數?
  • 新增連接類型時,只需實現ConnectionType結構體的函數,無需修改上層邏輯?

這種設計帶來的優勢:?

  • 接口與實現分離,降低模塊間耦合?
  • 便于擴展新的連接類型?
  • 保持上層代碼的穩定性?
  • 統一的錯誤處理和狀態管理

五、架構設計亮點?

模塊化設計: 每種連接類型作為獨立模塊實現,便于維護和擴展?
條件編譯支持: 通過編譯選項控制TLS、RDMA等可選模塊的編譯和注冊?
統一抽象層: 通過函數指針實現多態,簡化上層使用?
漸進式初始化: 從連接注冊到監聽器啟動,形成完整的初始化流程?
靈活的配置體系: 支持多種連接類型的并行配置和啟動?

valkey的網絡管理架構通過這種分層抽象和接口統一,既保證了底層實現的靈活性,又為上層提供了簡單一致的使用方式,是高性能網絡服務的典型設計模式。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/89781.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/89781.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/89781.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【解碼文本世界的“隱形分界線”:Windows與Linux回車換行之謎】

在計算機的文本世界里&#xff0c;回車&#xff08;Carriage Return&#xff0c;CR&#xff09;和換行&#xff08;Line Feed&#xff0c;LF&#xff09;是兩個看似簡單卻意義非凡的字符。它們如同文本中的“隱形分界線”&#xff0c;默默地劃分著段落與行&#xff0c;影響著文…

【Project】ELK 7.17.16 日志分析系統部署

ELK 日志分析系統集群部署 本文檔基于 Rocky Linux 9.4 系統&#xff0c;部署 ELK 7.17.16&#xff08;長期支持版&#xff09;集群 案例準備 1. 節點規劃IP主機名部署組件角色說明192.168.100.150kafka01Elasticsearch、Kibana主節點&#xff08;master&#xff09; 可視化192…

分布式定時任務系列13:死循環是任務觸發的銀彈?

傳送門 分布式定時任務系列1&#xff1a;XXL-job安裝 分布式定時任務系列2&#xff1a;XXL-job使用 分布式定時任務系列3&#xff1a;任務執行引擎設計 分布式定時任務系列4&#xff1a;任務執行引擎設計續 分布式定時任務系列5&#xff1a;XXL-job中blockingQueue的應用 …

Flutter基礎(前端教程①③-單例)

現實類比&#xff1a;公司打印機假設你們公司有一臺共享打印機&#xff1a;非單例&#xff08;重復創建&#xff09;&#xff1a;每個員工都自己買一臺打印機放在工位上結果&#xff1a;浪費錢&#xff0c;占空間&#xff0c;難維護單例&#xff08;唯一實例&#xff09;&#…

力扣刷題 -- 965.單值二叉樹

題目示例&#xff1a; 思路分析代碼實現 bool isUnivalTree(struct TreeNode* root) {if(rootNULL){return true;}if(root->left && root->val ! root->left->val){return false;}if(root->right && root->val ! root->right->val){re…

uni-api交互反饋組件(showToast)的用法

歡迎來到我的UniApp技術專欄&#xff01;&#x1f389; 在這里&#xff0c;我將與大家分享關于UniApp開發的實用技巧、最佳實踐和項目經驗。 專欄特色&#xff1a; &#x1f4f1; 跨平臺開發一站式解決方案 &#x1f680; 從入門到精通的完整學習路徑 &#x1f4a1; 實戰項目經…

借助它,在Web3投資賽道搶占先機

隨著互聯網技術的飛速發展&#xff0c;Web3的概念逐漸成為科技圈和投資界的熱門話題。Web3代表著下一代互聯網的發展方向&#xff0c;它強調去中心化、用戶主權和數據隱私保護。在這一新興領域&#xff0c;如何借助Web3技術搶占投資先機&#xff0c;成為許多投資者關注的焦點。…

驗證大語言模型不會算數但可以編寫算數的程序

摘要&#xff1a;本文通過幾個實例測試了大語言模型在數學計算、排序、統計等方面的能力。結果顯示&#xff0c;對于簡單字符統計、排序等任務&#xff0c;大模型能正確生成實現代碼&#xff0c;但當數據區分度降低時容易出錯。在計算學生分數排名任務中&#xff0c;大模型生成…

概率論與數理統計(八)

參數估計 通過取樣本&#xff0c;并用樣本構造函數&#xff0c;達成估計分布函數參數的目的 矩估計法 本質&#xff1a;用樣本的各階矩代替總體的各階矩&#xff0c;即取&#xff1a; E(X)X ̄1n∑iXiE(X2)1n∑iXi2E(X)\overline{X}\dfrac{1}{n}\sum_i X_i\\ E(X^2)\dfrac{1}…

服務器后臺崩潰的原因

當我們雙十一活動零點拼命刷新卻卡在支付完頁面&#xff0c;游戲頁面等不進去&#xff0c;公司系統癱瘓全體員工干瞪眼&#xff0c;服務器崩潰絕對是數字時代中的酷刑&#xff01;那服務器為什么會說崩就崩&#xff0c;用戶對于這種情況該如何進行避雷呢&#xff1f;服務器主要…

線程池與ThreadPoolExecutor源碼解析(上)

一、線程池線程池&#xff08;ThreadPool&#xff09;是一種線程復用的機制。它維護著若干個線程&#xff0c;任務來了就復用這些線程去執行&#xff0c;任務做完線程不會銷毀&#xff0c;而是回到池中等待下一個任務。為什么要用線程池&#xff1f;降低資源消耗&#xff1a;避…

Linux內核IP分片重組機制剖析:高效與安全的藝術

在IP網絡通信中,當數據包超過MTU限制時,路由器會將其拆分為多個分片。這些分片到達目標主機后,內核必須高效、安全地重組原始數據包。Linux內核的net/ipv4/inet_fragment.c實現了一套精妙的分片管理框架,完美平衡了性能和安全性需求。本文將深入剖析其設計哲學與關鍵技術。…

相機模型和對極幾何

一、相機模型 1.針孔相機模型-外參矩陣 1.世界坐標系到相機坐標系 世界坐標系&#xff1a;可以定義空間中任意一個位置&#xff0c;原點位置三個坐標軸方向坐標系姿態&#xff08;X,Y,Z&#xff09;相機坐標系&#xff1a;定義在相機上&#xff0c;原點是相機中心&#xff0c;z…

Git 常用命令與操作步驟

以下是 Git 常用命令與操作步驟 的整理&#xff0c;涵蓋日常開發中最核心的場景&#xff0c;適合快速查閱和上手&#xff1a;1. 初始化與克隆倉庫操作命令本地初始化倉庫git init克隆遠程倉庫git clone <倉庫URL> &#xff08;如 git clone https://gitlab.com/user/repo…

Leetcode-.283移動零

class Solution:def moveZeroes(self, nums: List[int]) -> None:"""Do not return anything, modify nums in-place instead."""pos0for i in range(len(nums)):if nums[i]!0:nums[pos],nums[i]nums[i],nums[pos]pos1本題運用雙指針來寫&…

在React中做過哪些性能優化?

1. 使用 React.memo 進行組件優化 問題:當父組件重新渲染時,子組件也會重新渲染,即使它的 props 沒有變化。 解決方案:使用 React.memo 包裹子組件,讓其只在 props 變化時才重新渲染。 const MyComponent = React.memo((props) => {// 子組件代碼 }); 2. 使用 useCa…

安裝docker可視化工具 Portainer中文版(ubuntu上演示,所有docker通用) 支持控制各種容器,容器操作簡單化 降低容器門檻

以下有免費的4090云主機提供ubuntu22.04系統的其他入門實踐操作 地址&#xff1a;星宇科技 | GPU服務器 高性能云主機 云服務器-登錄 相關兌換碼星宇社區---4090算力卡免費體驗、共享開發社區-CSDN博客 兌換碼要是過期了&#xff0c;可以私信我獲取最新兌換碼&#xff01;&a…

ansible批量部署zabbix客戶端

?ansible編寫劇本步驟 1??創建roles目錄結構2??在group_vars/all/main.yml中定義變量列表3??在tasks目錄下編寫tasks任務4??在files目錄下準備部署文件5??在templates目錄下創建j2模板文件6??在handlers目錄下編寫handlers7??在roles目錄下編寫主playbook8??運…

螞蟻數科AI數據產業基地正式投產,攜手蘇州推進AI產業落地

近日&#xff0c;螞蟻數科AI數據產業基地在太倉智匯谷科技創新園正式投產。該基地作為蘇州市首個AI數據產業基地&#xff0c;旨在通過跨行業人才與前沿技術&#xff0c;為長三角制造業、金融、醫療等領域的大模型落地提供場景化、高質量的訓練數據支撐。數據被視為AI學習的核心…

計算機的網絡體系及協議模型介紹

目錄 1、網絡協議介紹 1.1、定義 1.2、基本作用 1.3、協議的主要內容 2、網絡協議分層 2.1、協議分層原因 2.2、網絡協議分層的缺點 2.3、OSI協議和TCP/IP協議的聯系 3、TCP/IP 協議族 3.1、定義介紹 3.2、組成 1、應用層 2、運輸層 3、網絡層 3.3、底層流程 4、…