二十人的团队,买了 8 核 16G,监控上内存常年只用一半,但每隔几天就有人喊卡。这个场景我见过太多回了,而且每次排查的结论都一样:不是机器不够大,是估容量的口径从一开始就错了。你盯着的是"二十个人"这个静态数字,机器真正承受的却是"这一刻有几个 kernel 在跑、每个占了多少内存"这个动态数字。前者一天之内基本不变,后者能在十分钟内从 2 翻到 12。用静态数字去采购动态负载的机器,买到什么都不对——买小了有人喊卡,买大了监控曲线永远好看但你多花了钱。
说白了,这类交互式分析平台的容量,压根不应该按注册人数算。你只要记住下面这几条:
控制面(登录、调度、转发)几乎不花钱,钱全花在每个用户自己的那一台 Notebook Server 和它拉起来的 kernel 上。
kernel 的内存是只涨不降的,跑完一个大表不会自动还回来,"平均内存"这个指标在容量规划里基本没有参考价值,要看峰值和常驻。
真正的容量单位是"峰值同时活跃 kernel 数",二十人的团队同一时刻真正在跑的通常只有三五个。
不给单个 kernel 设内存上限、又不做空闲回收,三五个失控的 cell 就能把一台大机器拖垮,而且拖垮的是全组人。
磁盘必须单独算一笔,notebook 的输出和自动保存的 checkpoint 会悄悄把盘写满,尤其在多人共用一个目录的时候。
先把这个矛盾拆开。监控图上那条"内存使用率"通常是采样出来的,一分钟一个点,一天平均下来确实只有百分之四五十。但人感受到的"卡"不是平均值,是某个瞬间:swap 开始动了、内核开始杀进程、或者 kernel 干脆被 OOM 掉重连一次。这个瞬间可能一天只出现两三次,每次持续几分钟,采样曲线上就是一个不起眼的小尖刺。你按平均值判断机器够用,用户按尖刺判断机器垃圾,两边说的都是事实,只是看的不是同一个数。
为什么会有尖刺?因为交互式分析的使用是稀疏而突发的。一个典型场景(下面这类描述都是典型部署思路,并非特指某一真实客户):上午十点,有三个人在跑探索性分析,每人一个 kernel;十点半,其中一个人写了个循环,把一年的明细数据读进内存做 groupby,单个 kernel 从 800M 涨到 6G;同一时间另一个人在导出一批图表。二十分钟之内,这台机器的内存从 4G 冲到 14G,然后又跌回 5G。跌回去是因为 kernel 被回收了或者被人手动重启了,但那二十分钟里所有人的操作都在变慢,包括那十几个只是打开页面看一眼结果的人。
所以"二十人"这个数字在容量规划里的作用只有一个:它决定了峰值并发的上界,而不是均值。二十个人里可能有五个人这周在外出差、三个人这周只写文档、剩下的人也只在下午集中跑一阵。把二十直接乘上一个"人均 2G"得出 40G,是最典型的浪费;反过来,把二十乘上一个"人均 500M"得出 10G,又会在某天下午崩掉。两条路都错在用了"人数 × 人均"这个乘法。
要算对账,得先知道这套东西由哪几块组成,以及每一块到底吃什么资源。很多团队一上来就说"要不要把控制面单独放一台机器",问这个问题的人往往默认控制面很重,其实正相反。
Hub 是控制面,负责登录鉴权、用户管理、决定把谁的 server 拉到哪里去。它本质上是一个 Web 应用加一个数据库,主要吃内存里的少量常驻对象和一堆磁盘上的小读写,CPU 常年趴着。二十人的团队,Hub 那一份开销在整个机器的资源盘子里几乎可以当作舍入误差。Proxy 是转发层,负责把外部请求按路径分到对应的用户 server 上,它吃的是连接数、文件描述符和一点点转发开销,不占算力。一个用户开五个标签页,Proxy 那边就是五条长连接,跟这个用户跑了多大的模型毫无关系。Spawner 只在"拉起"这个动作发生时工作,是短暂的、脉冲式的开销,拉完就退场。
真正吃资源的是单用户 Notebook Server——每个活跃用户一份,独立进程或独立容器,Python 解释器、加载的包、Web 服务端都在里面。它的开销随"当前活跃用户数"线性增长,而且基数不小。再往下是 kernel 进程,它是真正执行代码的地方,也是内存曲线上那个尖刺的来源。server 和 kernel 的关系要分清:一个 server 可以挂着零个、一个或者好几个 kernel,不跑代码的 server 也会占一份基础内存,但这份基础内存远小于一个正在跑大表的 kernel。
把这几块拆开看,结论就很清楚了:控制面几乎不花钱,钱全花在用户自己的那一份上。这也直接回答了要不要单独给 Hub 一台机器的问题——二十人到五十人的规模,单独放一台小机器多半是浪费,还多出一个跨机网络与管理面。真正值得单独拆出去的理由不是性能,而是可用性与运维边界:你想让控制面的重启不影响正在跑的 kernel,或者你打算把用户 server 排到多台机器上时,Hub 才需要独立部署。
下面这张表是这套平台在一次容量规划里要逐项过一遍的账,六行对应六个组成部分,每一行都问了同一个问题:它随人数增长吗?能不能被限制?
| 组成部分 | 主要吃什么资源 | 是否随人数线性增长 | 决定因素 | 能不能被限制 |
|---|---|---|---|---|
| Hub 控制面 | 少量常驻内存、数据库读写 | 基本不随,注册人数只影响库表大小 | 登录频次、会话数量 | 可以,但通常没必要设 |
| Proxy 转发层 | 连接数、文件描述符、转发带宽 | 随并发连接增长,不随注册人数 | 同时在线会话与标签页数 | 可以,靠连接数与超时配置 |
| Spawner | 拉起瞬间的 CPU 与短时内存 | 不常驻,随启动并发脉冲式增长 | 同时启动的人数、镜像是否已预热 | 可以,靠并发启动数限制 |
| 单用户 Notebook Server | 常驻内存、少量 CPU、文件句柄 | 随当前活跃人数线性增长 | 活跃用户数与空闲回收策略 | 容器化后可以,本地多进程较难 |
| kernel 进程 | 内存为主,执行期间吃 CPU | 随同时活跃 kernel 数增长,且只涨不降 | 数据规模、包的体量、是否及时重启 | 容器化后可以设硬上限,否则很难 |
| 共享存储目录 | 磁盘容量与 IOPS | 随人数与产出物累积增长,不随并发 | 输出文件大小、checkpoint 频率、清理策略 | 可以,靠配额与定期清理 |
看这张表有一个很实用的读法:把"随人数线性增长"这一列里写着"基本不随"和"不常驻"的行划掉,剩下的才是你要掏钱买的部分。Hub、Proxy、Spawner 三行划掉之后,采购清单上只剩两样东西——给活跃用户 server 和 kernel 准备的内存,以及给所有人产出物准备的磁盘。这两样也是唯二会真正决定机器规格的东西。
这是最容易被人忽略、也最容易让容量估算翻车的一条。一个 kernel 进程从启动到消亡,它的内存占用曲线基本上是一条向上的阶梯,中间偶尔有极小的回落,但绝不会回到起点。原因是多方面的,讲三个最实际的。
一是导入的包会常驻。你在第一个 cell 里 import 一堆数据处理和绘图的库,这些模块的代码对象、常量、缓存就留在进程里了,除非你重启,否则一直占着。二是读进来的数据会常驻。一个 DataFrame 只要还有引用指向它,哪怕你后面再也用不上,它也不会消失。三是中间计算结果会常驻。探索性分析的特点就是你不知道自己要什么,所以会反复试,每一步的中间结果都被变量抓着,堆在一起。
更麻烦的是,就算你手动 del 掉了变量、手动触发了垃圾回收,进程向操作系统申请的那些内存也未必会还回去。Python 的内存分配器有自己的池化管理逻辑,它把释放出来的空间留在自己手里等着下次用,于是你在系统层面看到的 RSS 常常纹丝不动。这个现象让很多人的直觉失效:我明明把大表删了,怎么内存还是这么高?答案是你删掉的是对象,不是进程占用的那一块地址空间。
于是"平均内存"这个指标在容量规划里基本失去意义。你算出来的"人均 800M"可能是一天里二十个采样点的平均,但决定机器死活的是那个最高的点。正确的做法是看两个值:单个 kernel 的峰值常驻内存,以及这个峰值持续多久。前者决定你要买多少内存,后者决定你要不要做回收。一个 kernel 峰值 6G 但只持续五分钟,和一个 kernel 峰值 6G 并一直挂着三天,对机器的压力完全不是一回事——后者才是真正的灾难,因为它把 6G 从"瞬时尖刺"变成了"永久占用"。
顺带说一句,这也解释了为什么"重启 kernel"在这类平台里是一个正经的运维动作,而不是用户偷懒。它是唯一能把内存彻底还回来的手段。团队里应该形成习惯:一段探索跑完、结论已经落到文件或数据库里之后,顺手重启一下 kernel,把内存还回池子。这个习惯比多买 8G 内存管用得多。
既然单 kernel 的常驻是峰值,那总容量就是一句乘法:峰值同时活跃 kernel 数 × 单个 kernel 的峰值常驻内存,再加上系统本身、页面缓存、以及你预留的安全余量。这个式子里的第一个因子,才是"容量单位"。
二十人的数据科学小团队共用一台机器做探索分析,最典型的情况是:同一时刻真正在跑代码的只有三五个 kernel。原因是这类工作天然稀疏——有人在开会,有人在写文档,有人在看别人已经跑出来的结果,有人只是开着页面等着下午的会。真正按下运行键的窗口很短,而且彼此错开。这类团队按三五个 kernel 的峰值来买内存就够,按二十个人买会浪费掉一大半。
但把场景换成教学培训班,结论立刻反转。几十个学员同时上机,是有强同步性的:老师说"现在大家一起跑这段",一秒钟内几十个 kernel 全部启动,全部读同一份数据集,全部占上内存。这时候峰值同时活跃 kernel 数几乎等于学员人数,而且每个人跑的东西还一模一样,内存曲线会是一条陡峭的直线。培训班场景必须按人数上限估,而且要预留启动风暴——几十个进程同时拉起时,CPU 和磁盘 IO 会先于内存成为瓶颈,启动超时的配置也要跟着放宽。
内部 BI 与临时取数平台是第三种形态。它的特点是 kernel 数量可能不少,但单个 kernel 的常驻很低——查询推到数据库里做,拉回来的只是结果集。这种场景真正的瓶颈往往不是内存,而是并发连接数和外部数据库的压力。给这种平台买机器,内存可以保守,但要留足 CPU 和连接数,同时要想清楚要不要给每个人设查询超时。
还有一个必须写的反例:如果你的需求只是"交付成品报表",那上交互式分析环境就是过度设计。报表是定时的、参数固定的、结果可预期的,用调度系统跑一批脚本、把结果推到看板或者邮件里,成本和维护量都比一个交互式平台低一个数量级。交互式环境的价值在于"人要在里面思考",如果你不需要人在里面思考,就不要为它付这份钱。
空闲回收是这类平台里性价比最高的一个配置项,也是最容易配错的一个。配错的原因几乎总是同一个:只判了一个维度。
这两个维度分别是kernel 空闲时长和server 空闲时长。kernel 空闲指的是这个 kernel 多久没有执行任何代码了,判定依据通常是最后一次执行的时间戳。server 空闲指的是这个用户的 server 多久没有任何 HTTP 活动了,判定依据是最后的 API 请求时间。
只按 server 判定会发生什么?最常见的情况是这样的:用户打开了一个 notebook,跑完最后一段代码,然后就去开会了,浏览器标签一直开着。这个标签页会持续向服务端发心跳、拉状态、保活长连接,于是 server 永远"有活动",永远不会被判定为空闲。但那个 kernel 可能已经六个小时没执行过任何东西了,几 G 内存就这么一直占着。这种"僵尸 kernel"是内存浪费的最大来源,而在只按 server 判定的配置下,你永远收不掉它们。
只按 kernel 判定呢?会误伤。用户在读一个很长的输出、在翻一小时前跑出来的图表、在慢慢写 markdown 说明,这些时候 kernel 确实没执行代码,但用户还坐在屏幕前。你在这种情况下把 kernel 收掉,用户点下运行键的瞬间,会看到一个空白的上下文——变量没了、导入没了、之前跑过的中间结果全没了,得从头重跑。如果这段重跑要二十分钟,你就会被记恨很久。更隐蔽的一种是用户在终端里跑了个后台任务、或者挂着一个长时间的训练,代码执行层面可能处于等待状态,但工作绝不能中断。
所以正确的做法是两个维度都要判,且要分层配:kernel 空闲用一个较短的阈值(比如几十分钟量级),server 空闲用一个较长的阈值(小时量级),并且让"server 空闲"这个条件作为兜底——任何一个条件满足就停掉对应的那一层,而不是停掉整个用户会话。别被忽悠着抄一个网上的配置值就上线,阈值应该跟着你们的作息走:午休一小时、下班到第二天早上,这两个空档是回收的黄金窗口,把阈值卡在这两个窗口里,既不误伤也收得干净。
还有两个配套的减痛措施,几乎没有成本,但效果很好。一是回收之前在前端给提示,让用户知道"你的环境空闲太久,即将被回收,点击继续使用",给一个几十秒的宽限期;二是回收之前把 notebook 文件本身保存好——注意,保存的是文件,不是内存里的变量。文件保存了,用户回来至少不用重写代码,只是要重跑一遍。这个区别决定了用户是会抱怨一句,还是会来投诉。
前面反复提到"设上限",但能不能设、设了有没有效,完全取决于你用什么方式把用户的 server 拉起来。这一条是选型阶段就要定的事,事后改代价很大。
第一种是本地多进程方式。Hub 直接在机器上 fork 出子进程,每个用户一个,用不同的端口和系统用户区分。它的优点是简单:不需要额外的依赖,装完就能用,排障也直观,ps 一下就看得到。缺点是隔离差,你很难给单个用户设一个硬性的内存上限。系统层面当然有资源限制的手段,但在多进程、多子进程的模型下,把限制准确地施加到"某一个用户的全部进程"这件事并不轻松,且其行为(超限后是直接被杀还是分配失败)也未必是你想要的样子。这种方式适合团队规模小、彼此信任、且大家都很自觉的场景。
第二种是容器化方式。每个用户的 server 跑在自己的容器里,内存上限、CPU 配额、甚至磁盘配额都可以直接写在配置里。这个能力的价值不在日常,而在出事的那一天:某个人的循环写错了无限增长,撞到自己容器的内存上限,结果是他自己的 kernel 重启,其他人毫无感觉。隔离性还带来一个附带好处——每个用户可以用自己需要的 Python 版本和依赖,互不干扰,这在数据科学团队里经常是刚需。代价是你要维护镜像、要多一层排障路径、启动也会慢一些。
第三种是排到外部资源池里跑。把用户 server 交给集群去调度,每台机器只是资源池里的一块砖。这条路的最大变化是:容量问题被转移成了队列问题。你不再需要精确算出"这台机器能扛几个 kernel",而是给每个用户声明 request 和 limit,剩下的交给调度器;资源不够时,新来的用户排队等待,而不是把机器拖垮。它对运维能力的要求最高,但也是几十人以上规模、或者需要弹性伸缩时最稳的一条路。顺带一提,如果团队分布在不同地点、或者需要给中国香港、中国台湾、中国澳门等地的同事提供服务,资源池化之后按地域分散部署也会顺畅很多。
这三种方式对应的关键能力,说到底就是一句话:能不能限制单个用户。只要答案是"能",一台机器上的二十个人就是二十个互不相干的租户;答案是"不能",那二十个人就是二十个共享同一根保险丝的室友,任何一个人跳闸,全屋黑灯。
几乎所有人在估容量时只算内存,磁盘随便给个几百 G 就完事了,然后半年后收到一条"磁盘使用率 95%"的告警。这个坑值得单独讲一段。
先说 home 目录的形态。要么是所有人共享一份存储,要么是每人各自一份。共享一份的好处是交换文件方便、一份数据大家都能读;代价是这份存储必须是所有机器都能访问的网络文件系统,本地盘就不够用了,而网络文件系统的 IOPS 和延迟会成为新的瓶颈,尤其在小文件很多的场景下。每人一份的好处是可以落在本机磁盘上,性能好、成本低;代价是用户被绑定在某台机器上,机器出问题时迁移麻烦,也做不到多人读同一份数据。选哪个,取决于你们的协作方式,而不是哪个技术更先进。
再说说为什么盘会满。notebook 的产出物比你想象的多:每一张渲染出来的图如果选择了保存到文件,就是一份图片;每一次导出结果集,可能是一份 csv 或者 parquet,而且 parquet 往往比你想的大;跑模型的人会留下 checkpoint,一个几百 M 到几个 G,而且通常不止一个;最关键的是,编辑器会自动保存 checkpoint 文件,这些隐藏目录里的历史版本在无人清理的情况下会一直堆积。这些文件单看都不大,但乘以二十个人乘以半年,就非常可观了。
多人共用一个目录时这个问题会被放大。盘满了之后,你要找出是谁写的,在一个所有人都有写权限的目录里做这件事很痛苦:文件名可能是"数据.csv""结果_final.csv""结果_final2.csv",看不出归属,也不敢随便删。所以共享目录一定要配配额,每个用户一个上限,用得快的人自己先撞墙,而不是拖着全组一起撞。同时要建立清理策略:checkpoint 历史按时间滚动删除,导出目录设保留天数,超过一定大小的中间文件引导写到对象存储里去。
实操上还有一条很朴素的建议:把系统盘和数据盘分开。系统盘只放程序,数据盘放 home 和输出。这样盘满了的时候,最坏情况是用户写不进文件,而不是整个系统连日志都写不了、连登录都登不进去。另外,给数据盘的容量增长留一条后路——在线扩容或者挂载新盘的能力,比一开始多买一倍容量更划算。
把这七节串起来,就是一套完整的选型口径,一共三层。
第一层是下限,用来保稳定。内存总量按"峰值同时活跃 kernel 数 × 单 kernel 峰值常驻 × 安全系数"算出来,这个数是底线,低于它就是赌运气。安全系数给多少,取决于你对峰值的估计有多不确定——估得准可以给小一点,估不准(比如刚上线的团队,还不知道大家会怎么用)就给大一点。这一层不能省,省了就会出现"监控常年一半却总有人喊卡"。
第二层是上限,用来保体验。给每个用户、每个 kernel 设内存与 CPU 上限,让失控的代价被限制在那一个人身上。这一层的价值不在日常的资源利用率,而在于它把"全组一起卡死"这种不可接受的故障,降级成"某个人的 kernel 重启"这种可接受的小事故。做不做这一层,是"能用"和"敢用"的分界线。
第三层是回收,用来压住中间那块。有了上限,最坏情况被兜住了;但如果不回收,僵尸 kernel 会把常驻总量一点点抬上去,最终让"峰值同时活跃"这个数字慢慢膨胀成"开着就算"。空闲回收做的就是持续把常驻水位压回真实需求附近。三层配合好之后,你甚至可以把第一层的内存买得保守一些,因为第三层保证了它不会被长期占用。
落到采购上,这套口径导出的结论跟很多人的直觉相反:这类平台的真正约束是内存总量而不是核数。交互式分析绝大多数时间是人在思考、机器在等,CPU 的峰值只在执行那几秒出现,而内存是二十四小时常驻的。你下单时应该按内存优先挑配比,先定内存总量,再看核数够不够撑住同时执行的那几个 kernel,最后才是磁盘。一万网络(朗玥科技旗下,深耕 19 年,成立于 2007 年,总部深圳南山)的云主机与裸金属支持按内存与磁盘配比自选,这种"先定内存、再配核数与盘"的下单顺序在这一类负载上尤其合适,工程师还能 1 对 1 协助把环境部署起来。
再补一条容易被漏掉的:核数也不是完全不重要。培训班那种"几十人同时启动"的场景,瓶颈会短暂地落在 CPU 和磁盘 IO 上;而 BI 取数那种短查询密集的场景,核数决定的是排队时长而不是能不能跑完。所以"内存优先"不等于"核数随便",而是说内存的优先级更高、且内存的余量更难事后补救——内存不够会导致进程被杀,核数不够只是慢一点。
这个问题没有一个通用数字,因为它取决于"峰值同时活跃 kernel 数"而不是人数。给你一个可操作的算法:先估团队里同一时刻会按下运行键的人有几个——数据科学小团队通常是总人数的两成左右,培训班接近百分之百,BI 取数平台介于两者之间。然后估单个 kernel 的峰值常驻,这个数只能靠你们自己的数据规模来定,最靠谱的办法是让业务同学照常跑一周,然后把每个 kernel 的内存峰值记下来。两个数相乘,再加三成到五成的安全余量,就是内存总量。人数只是用来校验这个结果有没有超过单机的合理范围,一旦算出来需要上百 G,就该考虑拆机器或者走资源池了。
二十人到五十人的规模,一般不建议。控制面的开销在整个盘子里是舍入误差级别,单独放一台机器等于多付一台机器的钱、多一个跨机网络、多一套备份与监控,换来的收益几乎为零。真正值得单独放的理由有三个:一是你想让控制面重启时不影响正在跑的 kernel,二是你已经要把用户 server 排到多台机器上,控制面必须有个稳定的落点,三是你的可用性要求高到需要做控制面的主备。如果这三条一条都不占,就和控制面一起挤在一台机器上,把省下来的预算加到内存里。
设上限的原则是"让正常的工作不撞墙,让失控的行为早点撞墙"。具体做法是看你们历史数据里单个 kernel 峰值的分布:把常见的峰值当作基准,上限设在基准的两倍左右,这样日常的稍大一点的探索不会误杀,但一个失控的无限增长会在两倍的位置被拦下来。别设得太贴近日常峰值,否则用户会频繁遇到 kernel 重启,然后开始想办法绕开你的限制。也别忘了给系统本身留一块——不要把整机内存全部分给用户,操作系统、页面缓存、控制面都还要用。
关键不在于一个精确的分钟数,而在于对齐团队的作息。把 kernel 的空闲阈值卡在"明显超过一次正常思考停顿"的位置——人到中午吃饭、去开个会、下班回家,这些空档通常在一小时上下,把阈值放在这个量级,既不误伤正在读结果的人,也能收掉真正离开的人。server 的空闲阈值可以放得更长,作为兜底。无论设多少,务必配上前端提示和宽限期,并且在回收前保存好 notebook 文件。用户能接受的不是"被回收",而是"被回收了但代码还在、点一下就恢复"。
技术上能做到协同编辑,但你要先想清楚代价。同一份 notebook 背后是同一个 kernel 还是各自的 kernel,决定了完全不同的行为:共用一个 kernel 意味着两个人共享同一份内存状态,一个人跑的代码会改变另一个人的变量,这在探索分析里极易产生"我明明没改这个变量"的困惑;各自独立 kernel 又会让同一份文件里的输出互相覆盖,保存冲突频繁。多数团队的实际做法是:协作靠版本管理和评审,不靠实时共同编辑。真要一起看,就用只读分享或者把结果导出成报告。
判断标准只有一个:你需不需要"限制单个用户"。如果团队小、彼此信任、出问题互相喊一声就能解决,本地多进程完全够用,别为了技术先进而增加一层维护负担。但只要出现下面任何一种情况,就该上容器:团队里有人的数据规模明显大于其他人、需要不同的 Python 版本或依赖、有外部人员或临时学员使用、或者你无法接受一个人拖垮全组。容器化的额外成本是镜像维护和排障路径变长,这笔账在人数上去之后是划算的。
别拍脑袋,把它拆成四份来估:每人一份代码与小数据的基础占用、导出结果与图表的累积、模型 checkpoint 的峰值、以及自动保存的历史版本。前两项可以按人数乘一个经验值,第三项要去问具体跑模型的人,第四项取决于你保留多少份历史。估完之后做三件事:给每个用户设配额、设自动清理策略、把系统盘和数据盘分开。做完这三件事,你可以放心地把容量估得紧一点,因为盘快满时你有明确的处置路径,而不是半夜起来手动删文件。
本文讲的是通用工程原理与容量规划口径,没有实机压测数据,不提供任何具体数字,文中出现的数量级都只是帮助你建立量感的示意,不能直接当作采购依据。不同团队的数据规模、包的体量、使用习惯差异极大,同一个"二十人"的配置在不同团队身上可能相差数倍,唯一可靠的做法是先小规模跑起来、把 kernel 的内存峰值和同时活跃数记上一两周,再据此定机器的规格。
文中提到的软件组件、拉起方式、配置项名称,均以实现无关的方式描述,具体名称与可用参数请以你所选版本的官方文档为准;不同版本之间配置项的行为可能有变化,升级前务必在测试环境验证一遍回收与限额相关的设置。涉及一万网络的产品形态、可售规格、部署支持范围与商务条款,请以官网实时信息为准,本文不作任何承诺。具体以签约时最新报价与合同为准。
Copyright © 2013-2020 idc10000.net. All Rights Reserved. 一万网络 科技有限公司 版权所有 深圳市科技有限公司 粤ICP备07026347号
本网站的域名注册业务代理北京新网数码信息技术有限公司的产品