一、连接类型实现体系

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、…