无服务器架构设计模式和最佳实践 Serverless Architectural Patterns and Best Practices 李磊, AWS 解决方案架构师 Leon Li, Solutions Architect, Web Services 2017 年 9 月 26 日 Sep 26, 2017
议程 无服务器架构的特征和实践经典的三层架构批处理流式处理自动化处理中的无服务器应用 BMC 无服务器架构的经验
AWS 所提供的服务类型 On EC2 Managed Serverless EC2 EMR Elasticsearch Service AWS Lambda Cognito Kinesis Microsoft SQL Server ElastiCache RDS Redshift S3 API Gateway DynamoDB CloudWatch SQS AWS IoT
无服务器的设计模式建立在 Functions 之上 Functions 是最小的部署和扩展单元 按照请求来自动扩展, 用户无需为这些关注这些扩展的开销 无需为 idle 的请求付费 跳过了最无聊的部分, 也是越过了最难的部分
Lambda 的注意事项和最佳实践 AWS Lambda 是无状态的! 无状态的! 无状态的! 确保没有在计算上的耦合. 本地文件系统和子进程的扩展都和 Lambda 的请求共生命周期
Lambda 的注意事项和最佳实践 你的 Lambda Function 能在冰天 雪地中幸存下来么?(Code Start) 要注意初始化 AWS 客户端连接或者数据库连接的时候的变量 scope, 尽可能的复用连接 利用 CloudWatch Events 来做预热 ENIs for VPC 将会在 Code Start 时候被加载 冷启动时执行 import sys import logging import rds_config import pymysql rds_host = "rds-instance" db_name = rds_config.db_name try: conn = pymysql.connect( except: logger.error("error: def handler(event, context): with conn.cursor() as 仅在调用时被执 cur: 行
Lambda 的注意事项和最佳实践 文件系统如何考量? 别忘记我们还有 /tmp (512 MB 空间 ) exports.ffmpeg = function(event,context) { new ffmpeg('./thumb.mp4', function (err, video) { if (!err) { video.fnextractframetojpg('/tmp ) function (error, files) { } if (!error) console.log(files); context.done();...
Lambda 的注意事项和最佳实践 自定义 CloudWatch 指标 40 KB per POST 默认账户限制在 150 TPS Consider 通过 Kinesis 来聚合日志 def put_cstate ( iid, state ): response = cwclient.put_metric_data( Namespace='AWSx/DirectConnect', MetricData=[ { 'MetricName':'ConnectionState', 'Dimensions': [ { 'Name': 'ConnectionId', 'Value': iid }, ], 'Value': state, 'Unit': 'None
模式 1: 经典的三层架构
Web application CloudFront S3 Browser API Gateway Dynamic content in AWS Lambda Data stored in DynamoDB
无服务器架构 web app 安全实践 Browser CloudFront OAI Geo-Restriction Signed Cookies Signed URLs DDOS S3 Bucket Policies ACLs AuthZ API Gateway Throttling Caching Usage Plans AWS Lambda DynamoDB IAM IAM
无服务器架构 web app 安全实践 Browser CloudFront OAI Geo-Restriction Signed Cookies Signed URLs DDOS S3 Bucket Policies ACLs CloudFront AWS WAF HTTPS Disable Host Header Forwarding API Gateway Throttling Caching Usage Plans AWS Lambda DynamoDB AuthZ IAM IAM
无服务器架构 web app 监控 Browser CloudFront Access Logs in S3 Bucket CloudWatch Metricshttps://aws.amazon.com/ cloudfront/reporting/ S3 Access Logs in S3 Bucket Custom CloudWatch Metrics & Alarms AWS CloudTrail AWS WAF WebACL Testing Total Requests Allowed/Blocked Requests by ACL API Gateway logs Latency Count Cache Hit/Miss 4XX/5XX Errors AWS Lambda logs DynamoDB Latency Invocations Invocation Errors Throughput Duration Throttled Invocations Throttled Reqs Returned Bytes Documentation Streams
无服务器架构 web app 生命周期管理 AWS SAM (Serverless Application Model) - blog Code/Packages/ Swagger 在线研讨会 https://aws.amazon.com/cn/aboutaws/events/webinar/using-sam-to-build-aws-lambdaapplication09122017/ AWS Lambda DynamoDB Serverless Template Package & Deploy S3 Serverless Template w/ CodeUri AWS CloudFormation API Gateway package deploy CI/CD Tools
API Gateway 最佳实践 使用 mock 整合做到快速原型迭代 使用 Signed URL 和 API Gateway 的 Large Binary 功能的结合来上传到 S3 使用 request/response mapping 模版来更好的兼容历史遗留的应用 使用 Lambda 异步调用来更好的支持需要被处理很久的请求 (>30s)
Root / 使用简单代理模式 - greedy path https://github.com/awslabs/aws-serverless-express /{proxy+} ANY Your Node.js Express app 简洁高效 : 自动扩展 只为产生的请求付费
模式 2: 批处理
批处理的特征 大批的数据量 定期的或者被计划的任务 Extract Transform Load (ETL) 的工作模式 大部分情况下不会长期运行 大部分问题都能用 MapReduce 的模式来解决
无服务器架构 批处理 AWS Lambda: Mappers S3 Object AWS Lambda: Splitter. AWS Lambda: Reducer S3 Results. DynamoDB: Mapper Results
无服务器架构 批处理 AWS Lambda: Mappers S3 Object AWS Lambda: Splitter. AWS Lambda: Reducer S3 Results. S3: Mapper Results
注意事项和最佳实践 串联 mapper functions Lambda 批处理模式 vs. SQL (Hadoop / Spark 生态 ) 处理数据和 Lambda function 的并发和限制需要取得平衡 使用 DynamoDB/ElastiCache/S3 来管理 mapper functions 的状态 Lambda MapReduce Reference Architecture
无服务器架构的成本考量 200 GB 原始 Google Ngram data-set Serverless: 1000 并发 Lambda 调用 处理时间 : 9 minutes 成本 : $7.06
模式 3: 流式处理
流式处理的注意事项 高吞吐 近乎实时的处理能力 爆发性的间歇性流量 消息持久化 消息处理的保序
无服务器架构流式处理 KPL: Producer Kinesis: Stream Lambda: Stream Processor S3: Intermediate Aggregated Data S3: Final Aggregated Output Sensors CloudWatch Events: Trigger every 5 minutes Lambda: Scheduled Dispatcher Lambda: Periodic Dump to S3
扇出模式 Kinesis shards 的数量等同于 Lambda 的调用并发数量 高吞吐和低延时 vs 消息保序 KPL: Producer Kinesis: Stream Lambda: Dispatcher Lambda: Processors Sensors Increase throughput, reduce processing latency
更多关于扇出模式 谨记 Kinesis 的单个 Shard 的处理能力 1000 records / second 1 MB / second 使用扇出模式的时候, 考虑使用同步的 Lambda 调用方式 Rcoil for JS (https://github.com/sapessi/rcoil) Dead letter queue 重试失败的 Lambda 的调用
更多关于扇出模式 考虑使用 Step Functions 作为扇出模型的处理器
最佳实践 调教 Kinesis 每次调用 Lambda 触发器 batch size 的值, 默认是 100, 更大的值能够使得 Lambda 有更少的调用 调教 Lambda 的内存 更快的处理速度 尽量使用 KPL 的 Batch Message 功能来批量发送数据, 这样可以更充分的利用 Kinesis 的高吞吐特性
监控 Kinesis Stream metric GetRecords.IteratorAgeMilliseconds maximum
Kinesis Analytics Kinesis Streams Producer Kinesis: Kinesis Analytics: S3: Stream Window Aggregation Aggregated Output Sensors CREATE OR REPLACE PUMP "STREAM_PUMP" AS INSERT INTO "DESTINATION_SQL_STREAM" SELECT STREAM "device_id", FLOOR("SOURCE_SQL_STREAM_001".ROWTIME TO MINUTE) as "round_ts", SUM("measurement") as "sample_sum", COUNT(*) AS "sample_count" FROM "SOURCE_SQL_STREAM_001" Aggregation Time Window GROUP BY "device_id", FLOOR("SOURCE_SQL_STREAM_001".ROWTIME TO MINUTE);
成本考虑 评估 6 小时的消息处理速率 以 30 天为例作为成本考量 50,000 MESSAGES/SEC 20,000 20,000 20,000 10,000 10,000 1 2 3 4 5 6 HOURS
成本对比 无服务器架构 Kinesis Stream with 5 shards EC2 自建 Kafka cluster (3 x m3.large) Zookeeper cluster (3 x m3.large) Consumer (1 x c4.xlarge) Service Monthly Cost Service Monthly Cost Kinesis Streams $ 58.04 AWS Lambda $259.85 S3 (Intermediate Files) $ 84.40 CloudWatch $ 4.72 Total $407.01 EC2 Kafka Cluster $292.08 EC2 Zookeeper Cluster $292.08 EC2 Consumer $152.99 Total On-Demand $737.15 1-year All Upfront RI $452.42
Lambda architecture Batch Layer Data Sources Serving Layer Speed Layer
模式 4: 自动化
自动化处理所具备的特征 处理报警和各类事件 周期性的计划任务 审计和通知 对 AWS 服务功能性上的扩展 高可用 + 自动扩展
自动化处理 : 动态为 EC2 分配 DNS EC2 Instance State Changes CloudWatch Events: Rule Triggered AWS Lambda: Update Route53 Route53: Private Hosted Zone Tag: CNAME = xyz.example.com xyz.example.com A 10.2.0.134 DynamoDB: EC2 Instance Properties
自动化处理 : 从 S3 加载生成图片缩略图 S3: Source Bucket AWS Lambda: Resize Images S3: Destination Bucket Users upload photos Triggered on PUTs
CapitalOne Cloud Custodian CloudWatch Events: Rules Triggered AWS Lambda: Policy & Compliance Rules SNS: Alert Notifications AWS CloudTrail: Events CloudWatch Logs: Logs Read more here: http://www.capitalone.io/cloud-custodian/docs/index.html
最佳实践 文档化你的自动化处理的这些 event, 以及如何关闭和开启它们, 它们的依赖关系是怎样的 AWS API 会有调用的限制 throttling, 利用倒计时的 retry 机制处理 API 调用过程中的重试 (AWS SDKs 自带此功能 ) 记得将有意义的 CloudWatch 自定义指标打入 CloudWatch 便于运维 ( 例如定期为 EBS 打快照 )
客户案例 Architect, BMC Software
项目背景 去年 (2016),BMC 想开发下一代的云端产品来帮助客户在 DevOps 的管理和安全以及合规检查上的自动化管理工具. 适应多变的创新和产品迭代 在数据, 吞吐量和高可用的扩展上都有很高的要求和挑战 业务逻辑复杂 成本上更可控
Security and DevOps Automation
原本的想法 Data Data Blob Data Blob Data Blob Data Blob Blob collectors 1. Nginx 4. Kafka + Storm App App 5. Cassandra 挑战 : 6 个复杂的集群 缺乏运维经验 安装集群都需要很久 TCO 2. Zookeeper 3. Vault Ops Security Scale Monitor Dev Indexer Service 6. Elasticsearch
后来, 一个月就能出第一个版本 Data Data Blob Data Blob Data Blob Data Blob Blob collectors Ingest API Gateway Stream Write Service Stream Kinesis Resource Write Service DynamoDB s3 App App 简单并强大 时间可以都集中在开发上 自动扩展 运维成本低 一开始的成本就很低 成本风险小 API Gateway API App Services Manage Clusters Elasticsearch Service Indexer Service
还是会有 Ops, 世界上没有 NoOps 没有基础架构需要管理, 但轻量的运维工作还是存在的 你的 lambda 或者说你使用到的服务是否是正常工作的? 是否有很高的 error rate? ( 例如 5xx) 系统的响应延时是否很高? 你的数据库查询是否高效?
总结 无服务器架构的特征和实践 经典的三层架构 批处理 流式处理 自动化处理中的无服务器应用 BMC 无服务器架构的经验
Thank You!