近些日子帮了不少用户移植应用到了Windows Azure上,在这个过程中,我发现了用户对于Azure不太好的使用习惯,其原因一是对Azure技术不太了解,二是对Azure所推崇的理念不熟悉。对于公有云或者Azure的新用户来说,学习肯定是有一个过程的,这不是大问题。但是,有些问题必须在真正部署之前搞明白,否则不经意间导致数据丢失、系统停机就得不偿失了
1. [账户]搞清楚每个应用的订阅以及订阅的配额、计费方式、有效期
在Azure里面,用户需要区分账号和订阅。账号(live ID)是用来登陆门户的,对应一个自然人。而订阅对应配额、账单和付款信息。这就好比一个人有一个身份证(账号),但可以有多个手机号(每个手机号独立核算)。同一个Azure账号可以拥有多个订阅,每次部署Azure虚拟机或其他服务时,要选择一个订阅。每个订阅有一个主管理员,管理员可以添加其他用户成为该订阅的用户。这些添加的用户就可以共享该订阅资源,适合项目团队开发的场景。订阅的所有用户拥有相同的权限,唯一的区别是只有主管理员可以查阅账务信息。
在门户上,用户也可以过滤掉无关的订阅
由于每个订阅各不相同,因此部署之前弄清这些订阅信息是很必要的:
- 该订阅的类型,是试用、MSDN、随用随付还是多月计划?
- 该订阅的有效期
- 该订阅是否有配额?如果有,就需要定期检查配额剩余情况,避免造成订阅停用
- 该订阅是否存在其他用户,他们是否会误操作我部署的应用?
其中,搞清楚有效期是最重要的。如果订阅过期了,可能会造成所有数据被清空
2. [虚拟机和云服务] 一定要分清Blob盘和临时盘
Azure上的虚拟机上有两种磁盘,一种是存储在Blob存储上的,一种是存储在虚拟机所在物理机磁盘上的。前一种由于使用了Blob存储,其数据会按照Blob的存储策略在本地存3份,并在异地保持一份镜像,其数据的可用性和可靠性都很高,虚拟机通过网络访问这些Blob存储,不依赖于特定一台物理机。后一种依赖于物理机,如果物理机故障或进行维护,这个存储可能会被清空。显然,如果我们使用虚拟机的时候不分清楚磁盘类型,就会导致数据丢失
Azure不同类型的虚拟机的磁盘类型如下:
- IaaS的Windows虚拟机:C盘(系统盘)是Blob盘,D盘是临时盘
- IaaS的Linux磁盘:sda1(根目录)是Blob盘,sdb1(/mnt/resource)是临时盘
- PaaS的云服务的虚拟机磁盘:C/D/E全都是临时盘
千万不要把数据库表文件等重要数据放在临时盘上!
这些临时盘往往空间比较大,完全不用的话有些可惜。另外,临时盘在本地,存取数据要比Blob快。因此,临时盘适合存放一些临时数据,比如裸日志、中间结果、上传下载的缓存等等
那么,如果程序要存储文件到本地,本地系统盘空间又不够,怎么办?
- 对于IaaS虚拟机,可以从Azure门户的虚拟机页点击“附加空磁盘”,这样会分配一个空的Blob盘,挂接在虚拟机上。创建的磁盘还可以从原虚拟机分离,然后挂接给另一个虚拟机。不过一个磁盘不能同时挂给两个虚拟机
- 对于云服务虚拟机,不建议将文件存储在本地文件系统上,而是应该将文件直接存储在Blob上,需要修改文件访问API。如果不希望修改代码,则有两种办法:
- 如果应用需要读一些本地文件,或者需要在虚拟机上安装一些软件,则要在云服务启动脚本里面加入文件下载和软件安装的命令,具体可参考http://blog.csdn.net/shaunfang/article/details/8939681如果手动安装软件或者拷贝文件到云服务虚拟机,则虚拟机重启后一切改动都将消失。
- 如果应用不仅要读文件,还要写文件,那么就不能使用上面的方法,而必须用Azure Drive。它是将Blob磁盘挂载在虚拟机上的一种方法,可以参考http://blogs.msdn.com/b/azchina/archive/2010/04/12/windows-azure-windows-azure-drive.aspx。之所以不建议,是因为这不符合PaaS的理念。云服务的一个重要特性就是可以随意扩展,快速增删节点。如果使用Drive,就需要为每个虚拟机绑定一个Drive,这样不仅要维护Drive本身,还要维护Drive和虚拟机的对应关系。与其非要这样用,不如直接用IaaS
- 如果应用需要读一些本地文件,或者需要在虚拟机上安装一些软件,则要在云服务启动脚本里面加入文件下载和软件安装的命令,具体可参考http://blog.csdn.net/shaunfang/article/details/8939681如果手动安装软件或者拷贝文件到云服务虚拟机,则虚拟机重启后一切改动都将消失。
3. [网站、云服务与虚拟机]弄清负载均衡的机制
Azure为网站、云服务和虚拟机都提供了免费的负载均衡能力。关于负载均衡我们需要注意的一点就是它对Session的处理。一般来说,传统的负载均衡器有一种叫session粘滞(sticky)的机制,也就是会根据用户的session信息将用户请求转发到固定的一台机器上,这样,如果应用程序在服务器端存储session信息,那么用户与服务器交互就会顺畅,否则,就会发生用户session丢失和应用逻辑异常
在Azure上,云服务和虚拟机的负载均衡器都是纯网络层面的,其均衡机制是轮流将请求发给后端的服务器,不支持session粘滞. 这就要求后台服务器是无状态的,也就是无论将客户请求发给任何一个服务器,都可以得到正确的处理。如果现有的应用是有状态的,那么有两种解决办法:
- 将session信息在所有服务器间共享。具体实现方式包括:分布式缓存(比如Memcache,Azure Caching), session持久化(.NET和Java都支持用数据库存储session信息,而Azure还支持用Cache和Azure存储持久化.NET session信息: http://blogs.msdn.com/b/cie/archive/2013/05/17/session-state-management-in-windows-azure-web-roles.aspx)
- 在虚拟机上自行配置负载均衡集群,比如squid(linux), IIS ARR(windows). 微软的MSOpenTech团队提供了一个自动配置IIS ARR的方法:https://github.com/MSOpenTech/WindowsAzureToolkitForEclipseWithJava/tree/master/Utils/ARRConfigurationAgent。它原本是为了配置云服务里面的Java集群的,也可以用来配置其他IIS集群
网站服务的负载均衡稍有不同,它的负载均衡是由IIS ARR实现的,因此它原生支持session粘滞。其实现原理是,在每个响应里面添加ARRAffinity这个cookie,这样,下次同一个用户的请求就会被识别,然后发送到上次的服务器上。也就是说,不论应用是否主动写入cookie或是存取session,IIS都会为每个用户保持服务器的绑定关系。
4. [架构与运维]任何服务都可能会停机
尽管Azure的架构设计考虑了充分的冗余,但是仍然有可能会停机,这是任何服务都避免不了的。就算是5个9的可用性也会有一个停机的窗口。停机的原因有可能是非人为因素,比如断网、断电、硬件故障等等,也可能是人为计划性的停机维护。因此,作为用户,在部署应用到云平台时,需提前了解可能出现的风险和应对方案。Azure作为一个平台,或者云操作系统,会尽量做到不停机,但这只是平台层面的。从应用角度,用户也要考虑Azure提供的可用性是否能满足业务需求,如果不满足,如何进行设计从而提升应用整体的可用性。在大多数时候,更高的可用性都意为着更高的成本,因此,追求0宕机是不现实的,而Azure也无法实现这一点。开发者必须提前做好准备。
关于Azure的可用性,开发者和运维人员需要提前了解的是:
- Azure提供的各项服务是独立的,各种服务一般不会相互影响。比如,虚拟机服务整体故障时,数据库服务不受影响。用户可以随时登陆可用性监控台查看各个地区Azure各个服务的可用性http://www.windowsazure.com/en-us/support/service-dashboard/
- Azure为各个服务提供了独立的SLA承诺,绝大部分承诺的可用性指标是99.95%,也就是每年最多出现4.38小时的服务中断,如果超出,Azure会进行赔偿。
- 虚拟机和云服务的可用性承诺比较特殊。虚拟机服务的承诺是:由2个VM构成的集群的整体可用性是99.95%,而且这两个VM还要在同一个可用性集里面(http://www.windowsazure.com/en-us/manage/windows/common-tasks/manage-vm-availability/);而云服务的承诺是:每个Role需要至少2个实例,每个Role的可用性是99.95%。千万不要在一个Role内只部署一个虚拟机,这样停机的概率会很高。Azure每月会进行物理机OS和云服务虚拟机OS的升级,对于单实例的云服务来说,每次升级都可能造成云服务停止服务。
可见,对于单实例虚拟机,Azure不提供服务承诺。用户如果要部署数据库在虚拟机上,比如Mysql,需要自行配置HA,并把两个VM设定为同一个可用性组,这样Azure会将这两个VM放置到不同的故障域中(例如:不同机架)
另外,用户部署服务时,可以按照使用到的Azure服务画一个逻辑拓扑,如下图。然后逐一分析不同服务的停机对业务可能的影响,接着分析如何应对某个服务的停机或者故障。
如果要了解云计算架构下高可用性设计的最佳实践,可以参考下文:
防故障:弹性云体系结构的指南
http://msdn.microsoft.com/zh-cn/library/jj853352
5. [运维]做好数据备份
数据备份是老生常谈了,是运维工作的一个核心。尽管Windows Azure提供了完善的数据存储存储方案,比如一份数据在本地存三份,支持异地数据镜像等,但这只解决了数据物理损坏的问题,而没解决逻辑损坏的问题。比如,维护人员不小心删除了Blob上的文件、程序Bug删除或者修改了数据内容等等。因此,对云中的数据进行备份还是很有必要的。具体来说,每种数据的备份方式不尽相同。
- SQL数据库. Azure门户上为SQL 数据库提供了备份功能,用户点击备份按钮即可将数据库内容以Data Tier Application的格式导出到Blob存储上。用户可以下载该备份文件导入到本地的SQL Server上,也可以用该文件恢复一个SQL数据库。对于SQL数据库,建议采用自动化脚本定期进行备份,比如每天一次,保留7天。SQL数据库不支持定期任务,我们可以采用Windows任务计划或者Linux的cron来运行定期脚本。具体的命令可以参考https://github.com/richorama/SQLDatabaseBackup
- Blob存储。Blob存储本身不提供备份功能,只能进行快照。快照可以回滚文件到之前的版本,但是无法恢复被删除的文件(Azure不支持Container快照)。所以,对于重要的文件,建议编写脚本进行定期备份。备份的目的地址,可以是另一个存储账户,或者是本地。AzCopy这个工具可以用来在不同的存储账户之间进行文件拷贝,也可以用来在本地和Blob之间传输文件http://blogs.msdn.com/b/windowsazurestorage/archive/2013/04/01/azcopy-using-cross-account-copy-blob.aspx
- IaaS虚拟机。目前可用的方法,是进行虚拟机磁盘对应Blob文件的快照。具体可以参考http://blog.csdn.net/shaunfang/article/details/8933405#t0
- IaaS虚拟机文件。可采用各种传统文件备份工具。对于Windows Server,可以使用Azure的云备份服务http://blog.csdn.net/shaunfang/article/details/8933405#t1
- IaaS虚拟机中的数据库。可采用各种数据库的备份工具或者将数据库导出再进行文件备份
以上各种数据的备份都是定期进行的,建议编写程序或者脚本,专门找一台虚拟机运行