谷歌云免实名 谷歌云抢占式实例使用心得
话说去年冬天,我手头有个跑基因序列比对的Python脚本,单机跑完要37小时。老板说:“预算砍半,但结果不能晚。”我盯着AWS按量付费账单上跳动的$0.18/小时,默默打开了Google Cloud Console——不是因为信仰,是因为它家抢占式实例(Preemptible VMs)标价$0.023/小时,还带SSD。那一刻,我仿佛听见了钱包在笑,也听见了服务器在打呼噜。
先说人话:抢占式实例,不是“二手云主机”,而是Google把富余的物理机资源临时租给你,价格打骨折,但随时可能被叫停——就像你蹭朋友家WiFi看剧,他爸突然要开视频会议,你得立刻切回4G。官方承诺最长运行24小时,实际?我见过撑满24:00:01被强杀的,也见过刚启动3分钟就被弹出的,全看隔壁机房有没有新订单砸过来。
第一次用,我天真地配了个n1-standard-8(8核30GB),装好Miniconda,跑起脚本,泡了杯枸杞茶,蹲点等结果。两小时后回来——黑屏。SSH连不上,控制台显示“Instance terminated by system”。日志里只有冰冷一行:preempted。没有预警,没有告别,连句‘再见’都懒得打。我对着屏幕沉默三秒,然后默默重装环境、重传数据、重跑任务……直到第四次,我才意识到:这不是故障,是常态。
于是开始研究“怎么跟一个随时会跑路的队友长期合作”。核心就三条:别信它会活过24小时;所有状态必须落盘;每次启动都要当它是新机器。
第一关:数据不丢命。我直接放弃/tmp和内存盘,所有中间文件一律存到Cloud Storage。写了个小工具gs-sync.sh,每15分钟自动把当前工作目录打包上传,并带上时间戳和MD5校验码:gsutil -m cp -Z -r ./work gs://my-bucket/run-$(date +%s)/。关键来了——不是覆盖,是追加。这样哪怕实例挂了,下次拉起时,脚本先查gsutil ls gs://my-bucket/run-*/done.flag,找到最后一个成功标记,接着跑。相当于给任务装了个“断点续传U盘”。
第二关:启动即上岗。我写了个startup.sh,放在实例元数据里,开机自动执行。它干三件事:1)从GCS拉最新代码和配置;2)检查本地是否有未完成任务,有则恢复;3)启动主程序前,先发个HTTP请求到我的简易Webhook服务(就一行Python Flask),记下“实例ID + 启动时间 + 预期存活窗口”。这招救了我两次——某天发现所有实例都在凌晨3:17被集体回收,我立刻去查调度规律,果然,那是Google批量腾资源的“黄金时刻”。
第三关:监控别装高大上。我试过Stackdriver告警,太重;也试过自建Prometheus,太累。最后回归本质:写个watch-preempt.sh,每30秒curl一下http://metadata.google.internal/computeMetadata/v1/instance/preempted(需加header -H 'Metadata-Flavor: Google')。返回TRUE?立刻触发保存快照、上传日志、发企业微信通知。整个逻辑就12行Shell,却让我抢在实例咽气前3秒保住了最后一组中间结果。
当然,也有翻车现场。有次我把MySQL直接装在抢占式实例本地盘上,想着“反正只读”。结果某次预emption后,新实例拉起,应用连不上DB——因为旧实例磁盘已销毁,而我没做任何备份。后来改成Cloud SQL + 只读副本,应用层加重试逻辑,再没出过事。教训很土:云上的硬盘,比前任的承诺还不可靠。
成本对比?真香。同样n1-standard-4配置,按量付费月均$112,抢占式实测$9.6。省下的钱,够我给团队买半年咖啡。但别光算账——我做过统计:过去三个月,平均单实例存活16.3小时,最长一次23小时58分(我截图发了朋友圈,配文‘它在临终前完成了使命’),最短3分27秒(系统日志里写着‘Preemption reason: capacity_reclamation’,翻译过来就是‘你占的坑,别人要坐了’)。
还有几个反直觉冷知识:1)抢占式实例不能用GPU——不是技术限制,是Google怕你训练模型到一半被踢,投诉太多;2)关机后重启,不会保留抢占式身份,它会变成普通VM,价格翻倍,且无法再转回;3)跨区域迁移?不行。但同区域不同可用区之间,可以手动迁移镜像,再新建抢占式实例——这是我用来绕过“某可用区总被回收”的土办法。
最后说句掏心窝的:抢占式实例不是省钱的银弹,而是把“不确定性”明码标价卖给你。它适合能容错、可中断、有重试、爱折腾的场景——比如批量渲染、CI测试、参数扫描、离线ETL。如果你的任务要求“必须连续运行72小时”,请关掉这篇,去订Reserved Instances。别硬刚,不值得。
现在我的工作流已经进化成这样:Jenkins触发任务 → 创建抢占式实例集群 → 每个节点独立运行子任务 → 完成后自动销毁 → 结果汇总到BigQuery。整套流程跑下来,成本不到原来1/8,稳定性反而更高——毕竟,单点故障?不存在的,我有20台随时准备跑路的“敢死队”。
写完这篇文章,我顺手看了眼控制台:当前有3台抢占式实例在跑,状态都是RUNNING。其中一台的创建时间是今天上午9:42,已运行6小时21分。我端起杯子喝口凉茶,心里默念:兄弟,撑住,这单做完,我请你喝虚拟奶茶——虽然你喝不到,但我得信。
谷歌云免实名 (附赠一个彩蛋命令,复制粘贴就能用):gcloud compute instances create preempt-demo \
--preemptible \
--machine-type n2-standard-2 \
--image-family ubuntu-2204-lts \
--image-project ubuntu-os-cloud \
--scopes cloud-platform \
--metadata-from-file startup-script=startup.sh \
--zone us-central1-a

