{"componentChunkName":"component---src-templates-blog-detail-tsx","path":"/blog/2020-02-22-memory-configuration","result":{"data":{"currentBlog":{"id":"46b53fd9-c9e3-5156-aef4-dfda68d9e491","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/202033/1583244278485-0.jpg","authors":["Anycodes"],"categories":["guides-and-tutorials"],"date":"2020-02-22T00:00:00.000Z","title":"Serverless 的内存配置与超时时间","description":"当我们使用 Serverless 架构的时候，如何设置运行内存和超时时间呢？","authorslink":["https://www.zhihu.com/people/liuyu-43-97"],"translators":null,"translatorslink":null,"tags":["serverless","内存配置"],"keywords":"Serverless 内存配置,Serverless 超时时间,Serverless 统计方案","outdated":null},"wordCount":{"words":106,"sentences":22,"paragraphs":22},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-02-22-memory-configuration.md","fields":{"slug":"/blog/2020-02-22-memory-configuration/","keywords":["serverless","spa","云函数","内存","运行","time","时间","使用","durationList"]},"html":"<p>在上一篇文章<a href=\"https://serverlesscloud.cn/blog/2019-12-10-resource-cost/\">《Serverless 的资源评估与成本探索》</a>中，我们对性能和成本探索进行了些思考，在此就引出一个新的问题：当我们使用 Serverless 架构的时候，如何设置运行内存和超时时间呢？这里分享下我的评估方法供大家参考。</p>\n<p>首先在函数上线时，选择一个稍微大一点的内存。例如，这里执行一次函数，得到下图结果：</p>\n<p><img src=\"https://img.serverlesscloud.cn/202033/1583244075920-1.png\"></p>\n<p>那么将我的函数设置为 128M 或者 256M，超时时间设置成 3S。</p>\n<p>让函数跑一段时间，例如该接口每天触发约为 4000 次：</p>\n<p><img src=\"https://img.serverlesscloud.cn/202033/1583244075839-1.png\"></p>\n<p>将这个函数的日志捞出来写成脚本，做统计：</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">    import json, time, numpy, base64\n    import matplotlib.pyplot as plt\n    from matplotlib import font_manager\n    from tencentcloud.common import credential\n    from tencentcloud.common.profile.client_profile import ClientProfile\n    from tencentcloud.common.profile.http_profile import HttpProfile\n    from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException\n    from tencentcloud.scf.v20180416 import scf_client, models\n    \n    secretId = &quot;&quot;\n    secretKey = &quot;&quot;\n    region = &quot;ap-guangzhou&quot;\n    namespace = &quot;default&quot;\n    functionName = &quot;course&quot;\n    \n    font = font_manager.FontProperties(fname=&quot;./fdbsjw.ttf&quot;)\n    \n    try:\n        cred = credential.Credential(secretId, secretKey)\n        httpProfile = HttpProfile()\n        httpProfile.endpoint = &quot;scf.tencentcloudapi.com&quot;\n    \n        clientProfile = ClientProfile()\n        clientProfile.httpProfile = httpProfile\n        client = scf_client.ScfClient(cred, region, clientProfile)\n    \n        req = models.GetFunctionLogsRequest()\n    \n        strTimeNow = time.strftime(&quot;%Y-%m-%d %H:%M:%S&quot;, time.localtime(int(time.time())))\n        strTimeLast = time.strftime(&quot;%Y-%m-%d %H:%M:%S&quot;, time.localtime(int(time.time()) - 86400))\n        params = {\n            &quot;FunctionName&quot;: functionName,\n            &quot;Limit&quot;: 500,\n            &quot;StartTime&quot;: strTimeLast,\n            &quot;EndTime&quot;: strTimeNow,\n            &quot;Namespace&quot;: namespace\n        }\n        req.from_json_string(json.dumps(params))\n    \n        resp = client.GetFunctionLogs(req)\n    \n        durationList = []\n        memUsageList = []\n    \n        for eveItem in json.loads(resp.to_json_string())[&quot;Data&quot;]:\n            durationList.append(eveItem[&#39;Duration&#39;])\n            memUsageList.append(eveItem[&#39;MemUsage&#39;] / 1024 / 1024)\n    \n        durationDict = {\n            &quot;min&quot;: min(durationList),  # 运行最小时间\n            &quot;max&quot;: max(durationList),  # 运行最大时间\n            &quot;mean&quot;: numpy.mean(durationList)  # 运行平均时间\n        }\n        memUsageDict = {\n            &quot;min&quot;: min(memUsageList),  # 内存最小使用\n            &quot;max&quot;: max(memUsageList),  # 内存最大使用\n            &quot;mean&quot;: numpy.mean(memUsageList)  # 内存平均使用\n        }\n    \n        plt.figure(figsize=(10, 15))\n        plt.subplot(4, 1, 1)\n        plt.title(&#39;运行次数与运行时间图&#39;, fontproperties=font)\n        x_data = range(0, len(durationList))\n        plt.plot(x_data, durationList)\n        plt.subplot(4, 1, 2)\n        plt.title(&#39;运行时间直方分布图&#39;, fontproperties=font)\n        plt.hist(durationList, bins=20)\n        plt.subplot(4, 1, 3)\n        plt.title(&#39;运行次数与内存使用图&#39;, fontproperties=font)\n        x_data = range(0, len(memUsageList))\n        plt.plot(x_data, memUsageList)\n        plt.subplot(4, 1, 4)\n        plt.title(&#39;内存使用直方分布图&#39;, fontproperties=font)\n        plt.hist(memUsageList, bins=20)\n\n\n​        with open(&quot;/tmp/result.png&quot;, &quot;rb&quot;) as f:\n​            base64_data = base64.b64encode(f.read())\n​    \n\n        print(&quot;-&quot; * 10 + &quot;运行时间相关数据&quot; + &quot;-&quot; * 10)\n        print(&quot;运行最小时间:\\t&quot;, durationDict[&quot;min&quot;], &quot;ms&quot;)\n        print(&quot;运行最大时间:\\t&quot;, durationDict[&quot;max&quot;], &quot;ms&quot;)\n        print(&quot;运行平均时间:\\t&quot;, durationDict[&quot;mean&quot;], &quot;ms&quot;)\n    \n        print(&quot;\\n&quot;)\n    \n        print(&quot;-&quot; * 10 + &quot;内存使用相关数据&quot; + &quot;-&quot; * 10)\n        print(&quot;内存最小使用:\\t&quot;, memUsageDict[&quot;min&quot;], &quot;MB&quot;)\n        print(&quot;内存最大使用:\\t&quot;, memUsageDict[&quot;max&quot;], &quot;MB&quot;)\n        print(&quot;内存平均使用:\\t&quot;, memUsageDict[&quot;mean&quot;], &quot;MB&quot;)\n    \n        print(&quot;\\n&quot;)\n    \n        plt.show(dpi=200)\n​    except TencentCloudSDKException as err:\n​        print(err)</code></pre></div>\n<p>运行结果：</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">    ----------运行时间相关数据----------\n    运行最小时间:\t 6.02 ms\n    运行最大时间:\t 211.22 ms\n    运行平均时间:\t 54.79572 ms\n​    \n    ----------内存使用相关数据----------\n    内存最小使用:\t 17.94921875 MB\n    内存最大使用:\t 37.21875190734863 MB\n    内存平均使用:\t 24.83201559448242 MB</code></pre></div>\n<p><img src=\"https://img.serverlesscloud.cn/202033/1583244075858-1.png\"></p>\n<p>通过该结果可以清楚看出，近 500 次，每次函数的时间消耗和内存使用。</p>\n<p>可以看到时间消耗基本在 1S 以下，所以此处「超时时间」设置成 1S 比较合理；而内存使用基本是 64M 以下，所以此时内存设置成 64M 就可以。</p>\n<p>再举个例子，对于另外一个函数：</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">    ----------运行时间相关数据----------\n    运行最小时间:\t 63445.13 ms\n    运行最大时间:\t 442629.12 ms\n    运行平均时间:\t 91032.31301886792 ms\n\n​    \n​    ----------内存使用相关数据----------\n​    内存最小使用:\t 26.875 MB\n​    内存最大使用:\t 58.69140625 MB\n​    内存平均使用:\t 36.270415755937684 MB</code></pre></div>\n<p><img src=\"https://img.serverlesscloud.cn/202033/1583244076054-1.png\"></p>\n<p>假如说上一个函数，是一个非常平稳和光滑的函数，很容易预估资源使用率，那么这个函数则可以很明显看出波动。</p>\n<p>运行时间绝大部分在 150S 以下，部分不到 200S，最高峰值近 450S。这个时候，我们就可以业务需求来判定，450S 的请求波峰是否可以被中止。此时，我推荐将这个函数的超时时间设置为 200S。</p>\n<p>至于内存部分，可以看到绝大部分都在 40MB 以内，部分出现在 45-55MB，最高未超过 60MB，所以此时可以将函数设置为 64MB。</p>\n<p>就目前来说，云函数在执行时可能会有一定的波动。因此内存使用或超时时间在范围内波动是很正常的，我们可以根据业务需求来做一些设置，将资源使用量压到最低，节约成本。</p>\n<p><strong>我的做法基本就是分为两步走：</strong></p>\n<ol>\n<li>简单运行两次，评估一下基础资源使用量，然后设置一个较高的值；</li>\n<li>函数运行一段时间后，获取样本，再进行基本的数据分析和数据可视化，优化得到一个相对稳定的新数值。</li>\n</ol>\n<blockquote>\n<p><strong>传送门：</strong></p>\n<ul>\n<li>GitHub: <a href=\"https://github.com/serverless/serverless/blob/master/README_CN.md\">github.com/serverless</a> </li>\n<li>官网：<a href=\"https://serverless.com/\">serverless.com</a></li>\n</ul>\n</blockquote>\n<p>欢迎访问：<a href=\"https://serverlesscloud.cn/\">Serverless 中文网</a>，您可以在 <a href=\"https://serverlesscloud.cn/best-practice\">最佳实践</a> 里体验更多关于 Serverless 应用的开发！</p>","tableOfContents":""},"previousBlog":{"id":"a84bbf0e-0a9f-5404-814b-dcf1f80bf6a0","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020327/1585306882572-9.jpg","authors":["serverless 社区"],"categories":["meetup"],"date":"2020-02-27T00:00:00.000Z","title":"面对突发需求，如何借助 Serverless 快速上云 - 直播课","description":"腾讯云 Serverless 技术专家王俊杰分享突发需求下，如何使用 Serverless Framework 实现快速上云！","authorslink":["https://serverlesscloud.cn"],"translators":null,"translatorslink":null,"tags":["serverless","Meetup"],"keywords":"Serverless 全局变量组件,Serverless 单独部署组件,Serverless Component","outdated":null},"wordCount":{"words":68,"sentences":9,"paragraphs":9},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-02-27-suddenly-meetup.md","fields":{"slug":"/blog/2020-02-27-suddenly-meetup/","keywords":["serverless","云函数","serverless","Serverless","serverlesscloud","腾讯","福利"]}},"nextBlog":{"id":"f498b5f5-0532-5678-b689-59326ed05b48","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/202034/1583322939920-v2-1a569e74722930de772e470209db3c05_1200x500.jpg","authors":["jenswang"],"categories":["news","user-stories"],"date":"2020-02-21T00:00:00.000Z","title":"我在 GMTC 上的分享：腾讯 Serverless 前端落地与实践","description":"本文内容整理自腾讯 Serverless 技术专家王俊杰在 GMTC 2019 深圳站的演讲。","authorslink":["https://www.zhihu.com/people/jenswang"],"translators":null,"translatorslink":null,"tags":["serverless","Meetup"],"keywords":"Serverless 前端落地,Serverless 实践","outdated":null},"wordCount":{"words":661,"sentences":98,"paragraphs":97},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-02-21-gmtc.md","fields":{"slug":"/blog/2020-02-21-gmtc/","keywords":["koa","serverless","website","无服务器","云函数","Serverless","serverlesscloud","前端","serverless"]}},"recommendBlogs":{"edges":[{"node":{"id":"665f9ce2-4451-59fd-bf98-1861789d3b3b","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/Serverless_logo.png","authors":["AndreaPasswater"],"categories":["guides-and-tutorials","engineering-culture"],"date":"2018-03-19T00:00:00.000Z","title":"如何为无服务器开放源代码项目做贡献","description":"想要为无服务器开放源代码项目做贡献？您可以遵循下面的指南。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":96,"sentences":36,"paragraphs":36},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-03-19-how-contribute-to-serverless-open-source.md","fields":{"slug":"/blog/2018-03-19-how-contribute-to-serverless-open-source/","keywords":["serverless","无服务器","serverless","github","插件","服务器","贡献","示例","blog","contribute"]}}},{"node":{"id":"a3e92579-65c3-5159-937c-32d18c5df7d7","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/why-not/why-not-header.png","authors":["AndreaPasswater"],"categories":["guides-and-tutorials","operations-and-observability","engineering-culture"],"date":"2018-03-21T00:00:00.000Z","title":"不适合选择无服务器的情境及原因","description":"无服务器既有优点也有缺点。那么，哪些情境下不适合选择无服务器？原因又是什么呢？","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":163,"sentences":43,"paragraphs":43},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-03-21-when-why-not-use-serverless.md","fields":{"slug":"/blog/2018-03-21-when-why-not-use-serverless/","keywords":["faas","react","serverless","spa","无服务器","无服务器函数","无服务器架构","无服务器开发","服务器","twitter","serverless","blockquote","lang","script","en"]}}},{"node":{"id":"6a16520b-7886-582e-9182-64e50712d486","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/vendor+choice/serverless-data-portability.jpg","authors":["NickGottlieb"],"categories":["engineering-culture","guides-and-tutorials"],"date":"2018-06-20T00:00:00.000Z","title":"浅谈无服务器、数据锁定和供应商选择","description":"供应商选择是如今 IT 领导者需要考虑的最重要事项，而这一点可利用数据可移植性来实现。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":205,"sentences":33,"paragraphs":33},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-06-20-data-lockin-vendor-choice-portability.md","fields":{"slug":"/blog/2018-06-20-data-lockin-vendor-choice-portability/","keywords":["go","serverless","无服务器","无服务器架构","供应商","serverless","开发人员","数据","锁定","选择","服务"]}}},{"node":{"id":"94741abb-10ba-5db1-9756-cd1d573473fa","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/webstorm-ide/streamline-webstorm-serverless2.jpg","authors":["EslamHefnawy"],"categories":["guides-and-tutorials","engineering-culture"],"date":"2018-08-15T00:00:00.000Z","title":"如何使用 WebStorm 简化无服务器工作流程","description":"在本文中，我将和您分享如何使用 WebStorm 进行无服务器特定的 IDE 设置以及如何利用它来极大地加快无服务器工作流程。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":234,"sentences":54,"paragraphs":54},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-08-15-streamline-serverless-workflow-webstorm.md","fields":{"slug":"/blog/2018-08-15-streamline-serverless-workflow-webstorm/","keywords":["nodejs","serverless","无服务器","无服务器开发","serverless","WebStorm","webstorm","服务器","blog","assets"]}}},{"node":{"id":"713a0563-4bf9-5721-bacb-3b4ef609fe4a","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/camp-fire/camp-fire-housing-thumb.jpg","authors":["EricWyne"],"categories":["guides-and-tutorials","user-stories"],"date":"2018-12-05T00:00:00.000Z","title":"Serverless Twitter 机器人帮助为坎普山火受灾者安置住房","description":"加利福尼亚州的坎普山火致使数千人流离失所，为此，我构建了一个简单的 Serverless Twitter 机器人来帮助将受灾者安置在临时住房！","authorslink":["https://serverless.com/author/ericwyne/"],"translators":["Aceyclee"],"translatorslink":["zhihu.com/people/Aceyclee"],"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":157,"sentences":26,"paragraphs":26},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-12-05-serverless-twitter-camp-fire.md","fields":{"slug":"/blog/2018-12-05-serverless-twitter-camp-fire/","keywords":["serverless","无服务器","云函数","Serverless","org","住房","Twitter","函数","受灾","机器人","山火"]}}},{"node":{"id":"17c972d9-0583-51f6-9d5d-c2ba5f21b6a3","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/20191227/1577409288454-v2-577c2b21d600e3ea07f156f3e9d2d6b8_1200x500.jpg","authors":["Alfred Huang"],"categories":["guides-and-tutorials"],"date":"2019-08-21T00:00:00.000Z","title":"Serverless 的运行原理与组件架构","description":"本文重点探讨下开发者使用 Serverless 时经常遇到的一些问题，以及如何解决","authorslink":["https://zhuanlan.zhihu.com/ServerlessGo"],"translators":null,"translatorslink":null,"tags":["运行原理","serverless"],"keywords":"Serverless 运行原理,Serverless 组件架构","outdated":null},"wordCount":{"words":236,"sentences":33,"paragraphs":33},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-08-21-serverless-operation-architecture.md","fields":{"slug":"/blog/2019-08-21-serverless-operation-architecture/","keywords":["koa","serverless","云函数","Serverless","用户","函数","请求","实例","形态","业务","serverlesscloud"]}}},{"node":{"id":"ae4fd2f8-515c-5aec-b584-38427ef33f7e","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020114/1578989800047-part-00492-780.jpg","authors":["Anycodes"],"categories":["guides-and-tutorials","user-stories"],"date":"2019-09-16T00:00:00.000Z","title":"突破传统 OJ 瓶颈，「判题姬」接入云函数","description":"通过 Serverless 实现在线编程","authorslink":["https://www.zhihu.com/people/liuyu-43-97"],"translators":null,"translatorslink":null,"tags":["在线编程","云函数"],"keywords":"Serverless 在线编程,Serverless OJ","outdated":null},"wordCount":{"words":169,"sentences":30,"paragraphs":30},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-09-16-online-Judge.md","fields":{"slug":"/blog/2019-09-16-online-Judge/","keywords":["python","serverless","云函数","代码","函数","serverless"]}}},{"node":{"id":"545ab3d2-e14e-5cc2-8548-0e863eac942b","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/2019-10-deployment-best-practices/safeguard-header.png","authors":["FernandoMedinaCorey"],"categories":["guides-and-tutorials"],"date":"2019-10-14T00:00:00.000Z","title":"无服务器部署最佳实践","description":"了解部署无服务器应用时的一些最佳实践。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":221,"sentences":46,"paragraphs":46},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-10-14-serverless-deployment-best-practices.md","fields":{"slug":"/blog/2019-10-14-serverless-deployment-best-practices/","keywords":["serverless","无服务器","serverless","部署","服务器","开发人员","应用","安全措施","使用","函数"]}}}],"totalCount":31}},"pageContext":{"isCreatedByStatefulCreatePages":false,"blogId":"46b53fd9-c9e3-5156-aef4-dfda68d9e491","previousBlogId":"a84bbf0e-0a9f-5404-814b-dcf1f80bf6a0","nextBlogId":"f498b5f5-0532-5678-b689-59326ed05b48","categories":["guides-and-tutorials"]}}}