{"componentChunkName":"component---src-templates-best-practice-detail-tsx","path":"/best-practice/2020-05-08-wordcount","result":{"data":{"currentBlog":{"id":"249242aa-c81b-5ff8-9553-90e8792af73e","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020511/1589207417923-ZalNtxgQAC_small.jpg","authors":["Anycodes"],"categories":["best-practice"],"date":"2020-05-08T00:00:00.000Z","title":"云函数 SCF 与对象存储实现 WordCount","description":"本文将通过 MapReduce 模型实现一个简单的 WordCount 算法，区别于传统使用 Hadoop 等大数据框架，本文使用的是对象存储 COS 与云函数 SCF 的结合","authorslink":["https://zhuanlan.zhihu.com/ServerlessGo"],"translators":null,"translatorslink":null,"tags":["Serverless","WordCount"],"keywords":"Serverless 多环境配置,Serverless 管理环境,Serverless配置方案","outdated":true},"wordCount":{"words":181,"sentences":28,"paragraphs":28},"fileAbsolutePath":"/opt/build/repo/content/best-practice/2020-05-08-wordcount.md","fields":{"slug":"/best-practice/2020-05-08-wordcount/","keywords":["python","serverless","云函数","file","cos","bucket","client","event"]},"html":"<p>MapReduce 在维基百科中的解释如下：</p>\n<blockquote>\n<p>MapReduce 是 Google 提出的一个软件架构，用于大规模数据集（大于 1TB）的并行运算。概念「Map（映射）」和「Reduce（归纳）」，及他们的主要思想，都是从函数式编程语言借来的，还有从矢量编程语言借来的特性。</p>\n</blockquote>\n<p>通过这段描述，我们知道，MapReduce 是面向大数据并行处理的计算模型、框架和平台，在传统学习中，通常会在 Hadoop 等分布式框架下进行 MapReduce 相关工作，随着云计算的逐渐发展，各个云厂商也都先后推出了在线的 MapReduce 业务。</p>\n<p>本文将尝试通过 MapReduce 模型实现一个简单的 WordCount 算法，区别于传统使用 Hadoop 等大数据框架，本文使用对象存储 COS 与云函数 SCF 来实现。</p>\n<h2 id=\"理论基础\"><a href=\"#%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80\" aria-label=\"理论基础 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>理论基础</h2>\n<p>在开始之前，我们根据 MapReduce 的要求，先绘制一个简单的流程图:</p>\n<p><img src=\"https://img.serverlesscloud.cn/202058/2-7-1.png\"></p>\n<p>在这个结构中，我们需要 2 个云函数分别作 Mapper 和 Reducer；以及 3 个对象存储的存储桶，分别作为输入的存储桶、中间临时缓存存储桶和结果存储桶。在实例前，由于我们的函数即将部署在广州区，因此在广州区建立 3 个存储桶：</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"15365790692450720000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`对象存储1\tap-guangzhou\tsrcmr\n对象存储2\tap-guangzhou\tmiddlestagebucket\n对象存储3\tap-guangzhou\tdestcmr`, `15365790692450720000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">对象存储1\tap-guangzhou\tsrcmr\n对象存储2\tap-guangzhou\tmiddlestagebucket\n对象存储3\tap-guangzhou\tdestcmr</code></pre></div>\n<p>为了让整个 Mapper 和 Reducer 逻辑更加清晰，在开始之前先对传统的 WordCount 结构进行改造，使其更加适合云函数，同时合理分配\nMapper 和 Reducer 的工作：</p>\n<p><img src=\"https://img.serverlesscloud.cn/202058/2-7-2.png\"></p>\n<h2 id=\"功能实现\"><a href=\"#%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0\" aria-label=\"功能实现 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>功能实现</h2>\n<p>编写 Mapper 相关逻辑，代码如下：</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"12177112343154883000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`# -*- coding: utf8 -*-\nimport datetime\nfrom qcloud_cos_v5 import CosConfig\nfrom qcloud_cos_v5 import CosS3Client\nfrom qcloud_cos_v5 import CosServiceError\nimport re\nimport os\nimport sys\nimport logging\nlogging.basicConfig(level=logging.INFO, stream=sys.stdout)\nlogger = logging.getLogger()\nlogger.setLevel(level=logging.INFO)\nregion = u'ap-guangzhou'  # 根据实际情况，修改地域\nmiddle_stage_bucket = 'middlestagebucket'  # 根据实际情况，修改bucket名\ndef delete_file_folder(src):\n    if os.path.isfile(src):\n        try:\n            os.remove(src)\n        except:\n            pass\n    elif os.path.isdir(src):\n        for item in os.listdir(src):\n            itemsrc = os.path.join(src, item)\n            delete_file_folder(itemsrc)\n        try:\n            os.rmdir(src)\n        except:\n            pass\ndef download_file(cos_client, bucket, key, download_path):\n    logger.info(&quot;Get from [%s] to download file [%s]&quot; % (bucket, key))\n    try:\n        response = cos_client.get_object(Bucket=bucket, Key=key, )\n        response['Body'].get_stream_to_file(download_path)\n    except CosServiceError as e:\n        print(e.get_error_code())\n        print(e.get_error_msg())\n        return -1\n    return 0\ndef upload_file(cos_client, bucket, key, local_file_path):\n    logger.info(&quot;Start to upload file to cos&quot;)\n    try:\n        response = cos_client.put_object_from_local_file(\n            Bucket=bucket,\n            LocalFilePath=local_file_path,\n            Key='{}'.format(key))\n    except CosServiceError as e:\n        print(e.get_error_code())\n        print(e.get_error_msg())\n        return -1\n    logger.info(&quot;Upload data map file [%s] Success&quot; % key)\n    return 0\ndef do_mapping(cos_client, bucket, key, middle_stage_bucket, middle_file_key):\n    src_file_path = u'/tmp/' + key.split('/')[-1]\n    middle_file_path = u'/tmp/' + u'mapped_' + key.split('/')[-1]\n    download_ret = download_file(cos_client, bucket, key, src_file_path)  # download src file\n    if download_ret == 0:\n        inputfile = open(src_file_path, 'r')  # open local /tmp file\n        mapfile = open(middle_file_path, 'w')  # open a new file write stream\n        for line in inputfile:\n            line = re.sub('[^a-zA-Z0-9]', ' ', line)  # replace non-alphabetic/number characters\n            words = line.split()\n            for word in words:\n                mapfile.write('%s\\t%s' % (word, 1))  # count for 1\n                mapfile.write('\\n')\n        inputfile.close()\n        mapfile.close()\n        upload_ret = upload_file(cos_client, middle_stage_bucket, middle_file_key,\n                                 middle_file_path)  # upload the file's each word\n        delete_file_folder(src_file_path)\n        delete_file_folder(middle_file_path)\n        return upload_ret\n    else:\n        return -1\ndef map_caller(event, context, cos_client):\n    appid = event['Records'][0]['cos']['cosBucket']['appid']\n    bucket = event['Records'][0]['cos']['cosBucket']['name'] + '-' + appid\n    key = event['Records'][0]['cos']['cosObject']['key']\n    key = key.replace('/' + str(appid) + '/' + event['Records'][0]['cos']['cosBucket']['name'] + '/', '', 1)\n    logger.info(&quot;Key is &quot; + key)\n    middle_bucket = middle_stage_bucket + '-' + appid\n    middle_file_key = '/' + 'middle_' + key.split('/')[-1]\n    return do_mapping(cos_client, bucket, key, middle_bucket, middle_file_key)\ndef main_handler(event, context):\n    logger.info(&quot;start main handler&quot;)\n    if &quot;Records&quot; not in event.keys():\n        return {&quot;errorMsg&quot;: &quot;event is not come from cos&quot;}\n    secret_id = &quot;&quot;\n    secret_key = &quot;&quot;\n    config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, )\n    cos_client = CosS3Client(config)\n    start_time = datetime.datetime.now()\n    res = map_caller(event, context, cos_client)\n    end_time = datetime.datetime.now()\n    print(&quot;data mapping duration: &quot; + str((end_time - start_time).microseconds / 1000) + &quot;ms&quot;)\n    if res == 0:\n        return &quot;Data mapping SUCCESS&quot;\n    else:\n        return &quot;Data mapping FAILED&quot;`, `12177112343154883000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token comment\"># -*- coding: utf8 -*-</span>\n<span class=\"token keyword\">import</span> datetime\n<span class=\"token keyword\">from</span> qcloud_cos_v5 <span class=\"token keyword\">import</span> CosConfig\n<span class=\"token keyword\">from</span> qcloud_cos_v5 <span class=\"token keyword\">import</span> CosS3Client\n<span class=\"token keyword\">from</span> qcloud_cos_v5 <span class=\"token keyword\">import</span> CosServiceError\n<span class=\"token keyword\">import</span> re\n<span class=\"token keyword\">import</span> os\n<span class=\"token keyword\">import</span> sys\n<span class=\"token keyword\">import</span> logging\nlogging<span class=\"token punctuation\">.</span>basicConfig<span class=\"token punctuation\">(</span>level<span class=\"token operator\">=</span>logging<span class=\"token punctuation\">.</span>INFO<span class=\"token punctuation\">,</span> stream<span class=\"token operator\">=</span>sys<span class=\"token punctuation\">.</span>stdout<span class=\"token punctuation\">)</span>\nlogger <span class=\"token operator\">=</span> logging<span class=\"token punctuation\">.</span>getLogger<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\nlogger<span class=\"token punctuation\">.</span>setLevel<span class=\"token punctuation\">(</span>level<span class=\"token operator\">=</span>logging<span class=\"token punctuation\">.</span>INFO<span class=\"token punctuation\">)</span>\nregion <span class=\"token operator\">=</span> <span class=\"token string\">u'ap-guangzhou'</span>  <span class=\"token comment\"># 根据实际情况，修改地域</span>\nmiddle_stage_bucket <span class=\"token operator\">=</span> <span class=\"token string\">'middlestagebucket'</span>  <span class=\"token comment\"># 根据实际情况，修改bucket名</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">delete_file_folder</span><span class=\"token punctuation\">(</span>src<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">if</span> os<span class=\"token punctuation\">.</span>path<span class=\"token punctuation\">.</span>isfile<span class=\"token punctuation\">(</span>src<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">try</span><span class=\"token punctuation\">:</span>\n            os<span class=\"token punctuation\">.</span>remove<span class=\"token punctuation\">(</span>src<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">except</span><span class=\"token punctuation\">:</span>\n            <span class=\"token keyword\">pass</span>\n    <span class=\"token keyword\">elif</span> os<span class=\"token punctuation\">.</span>path<span class=\"token punctuation\">.</span>isdir<span class=\"token punctuation\">(</span>src<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">for</span> item <span class=\"token keyword\">in</span> os<span class=\"token punctuation\">.</span>listdir<span class=\"token punctuation\">(</span>src<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n            itemsrc <span class=\"token operator\">=</span> os<span class=\"token punctuation\">.</span>path<span class=\"token punctuation\">.</span>join<span class=\"token punctuation\">(</span>src<span class=\"token punctuation\">,</span> item<span class=\"token punctuation\">)</span>\n            delete_file_folder<span class=\"token punctuation\">(</span>itemsrc<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">try</span><span class=\"token punctuation\">:</span>\n            os<span class=\"token punctuation\">.</span>rmdir<span class=\"token punctuation\">(</span>src<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">except</span><span class=\"token punctuation\">:</span>\n            <span class=\"token keyword\">pass</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">download_file</span><span class=\"token punctuation\">(</span>cos_client<span class=\"token punctuation\">,</span> bucket<span class=\"token punctuation\">,</span> key<span class=\"token punctuation\">,</span> download_path<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    logger<span class=\"token punctuation\">.</span>info<span class=\"token punctuation\">(</span><span class=\"token string\">\"Get from [%s] to download file [%s]\"</span> <span class=\"token operator\">%</span> <span class=\"token punctuation\">(</span>bucket<span class=\"token punctuation\">,</span> key<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">try</span><span class=\"token punctuation\">:</span>\n        response <span class=\"token operator\">=</span> cos_client<span class=\"token punctuation\">.</span>get_object<span class=\"token punctuation\">(</span>Bucket<span class=\"token operator\">=</span>bucket<span class=\"token punctuation\">,</span> Key<span class=\"token operator\">=</span>key<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">)</span>\n        response<span class=\"token punctuation\">[</span><span class=\"token string\">'Body'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span>get_stream_to_file<span class=\"token punctuation\">(</span>download_path<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">except</span> CosServiceError <span class=\"token keyword\">as</span> e<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>get_error_code<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>get_error_msg<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> <span class=\"token operator\">-</span><span class=\"token number\">1</span>\n    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">upload_file</span><span class=\"token punctuation\">(</span>cos_client<span class=\"token punctuation\">,</span> bucket<span class=\"token punctuation\">,</span> key<span class=\"token punctuation\">,</span> local_file_path<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    logger<span class=\"token punctuation\">.</span>info<span class=\"token punctuation\">(</span><span class=\"token string\">\"Start to upload file to cos\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">try</span><span class=\"token punctuation\">:</span>\n        response <span class=\"token operator\">=</span> cos_client<span class=\"token punctuation\">.</span>put_object_from_local_file<span class=\"token punctuation\">(</span>\n            Bucket<span class=\"token operator\">=</span>bucket<span class=\"token punctuation\">,</span>\n            LocalFilePath<span class=\"token operator\">=</span>local_file_path<span class=\"token punctuation\">,</span>\n            Key<span class=\"token operator\">=</span><span class=\"token string\">'{}'</span><span class=\"token punctuation\">.</span><span class=\"token builtin\">format</span><span class=\"token punctuation\">(</span>key<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">except</span> CosServiceError <span class=\"token keyword\">as</span> e<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>get_error_code<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>get_error_msg<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> <span class=\"token operator\">-</span><span class=\"token number\">1</span>\n    logger<span class=\"token punctuation\">.</span>info<span class=\"token punctuation\">(</span><span class=\"token string\">\"Upload data map file [%s] Success\"</span> <span class=\"token operator\">%</span> key<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">do_mapping</span><span class=\"token punctuation\">(</span>cos_client<span class=\"token punctuation\">,</span> bucket<span class=\"token punctuation\">,</span> key<span class=\"token punctuation\">,</span> middle_stage_bucket<span class=\"token punctuation\">,</span> middle_file_key<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    src_file_path <span class=\"token operator\">=</span> <span class=\"token string\">u'/tmp/'</span> <span class=\"token operator\">+</span> key<span class=\"token punctuation\">.</span>split<span class=\"token punctuation\">(</span><span class=\"token string\">'/'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">[</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span>\n    middle_file_path <span class=\"token operator\">=</span> <span class=\"token string\">u'/tmp/'</span> <span class=\"token operator\">+</span> <span class=\"token string\">u'mapped_'</span> <span class=\"token operator\">+</span> key<span class=\"token punctuation\">.</span>split<span class=\"token punctuation\">(</span><span class=\"token string\">'/'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">[</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span>\n    download_ret <span class=\"token operator\">=</span> download_file<span class=\"token punctuation\">(</span>cos_client<span class=\"token punctuation\">,</span> bucket<span class=\"token punctuation\">,</span> key<span class=\"token punctuation\">,</span> src_file_path<span class=\"token punctuation\">)</span>  <span class=\"token comment\"># download src file</span>\n    <span class=\"token keyword\">if</span> download_ret <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">:</span>\n        inputfile <span class=\"token operator\">=</span> <span class=\"token builtin\">open</span><span class=\"token punctuation\">(</span>src_file_path<span class=\"token punctuation\">,</span> <span class=\"token string\">'r'</span><span class=\"token punctuation\">)</span>  <span class=\"token comment\"># open local /tmp file</span>\n        mapfile <span class=\"token operator\">=</span> <span class=\"token builtin\">open</span><span class=\"token punctuation\">(</span>middle_file_path<span class=\"token punctuation\">,</span> <span class=\"token string\">'w'</span><span class=\"token punctuation\">)</span>  <span class=\"token comment\"># open a new file write stream</span>\n        <span class=\"token keyword\">for</span> line <span class=\"token keyword\">in</span> inputfile<span class=\"token punctuation\">:</span>\n            line <span class=\"token operator\">=</span> re<span class=\"token punctuation\">.</span>sub<span class=\"token punctuation\">(</span><span class=\"token string\">'[^a-zA-Z0-9]'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">' '</span><span class=\"token punctuation\">,</span> line<span class=\"token punctuation\">)</span>  <span class=\"token comment\"># replace non-alphabetic/number characters</span>\n            words <span class=\"token operator\">=</span> line<span class=\"token punctuation\">.</span>split<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n            <span class=\"token keyword\">for</span> word <span class=\"token keyword\">in</span> words<span class=\"token punctuation\">:</span>\n                mapfile<span class=\"token punctuation\">.</span>write<span class=\"token punctuation\">(</span><span class=\"token string\">'%s\\t%s'</span> <span class=\"token operator\">%</span> <span class=\"token punctuation\">(</span>word<span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>  <span class=\"token comment\"># count for 1</span>\n                mapfile<span class=\"token punctuation\">.</span>write<span class=\"token punctuation\">(</span><span class=\"token string\">'\\n'</span><span class=\"token punctuation\">)</span>\n        inputfile<span class=\"token punctuation\">.</span>close<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        mapfile<span class=\"token punctuation\">.</span>close<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        upload_ret <span class=\"token operator\">=</span> upload_file<span class=\"token punctuation\">(</span>cos_client<span class=\"token punctuation\">,</span> middle_stage_bucket<span class=\"token punctuation\">,</span> middle_file_key<span class=\"token punctuation\">,</span>\n                                 middle_file_path<span class=\"token punctuation\">)</span>  <span class=\"token comment\"># upload the file's each word</span>\n        delete_file_folder<span class=\"token punctuation\">(</span>src_file_path<span class=\"token punctuation\">)</span>\n        delete_file_folder<span class=\"token punctuation\">(</span>middle_file_path<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> upload_ret\n    <span class=\"token keyword\">else</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> <span class=\"token operator\">-</span><span class=\"token number\">1</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">map_caller</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">,</span> context<span class=\"token punctuation\">,</span> cos_client<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    appid <span class=\"token operator\">=</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'Records'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'cos'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'cosBucket'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'appid'</span><span class=\"token punctuation\">]</span>\n    bucket <span class=\"token operator\">=</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'Records'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'cos'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'cosBucket'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'name'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">+</span> <span class=\"token string\">'-'</span> <span class=\"token operator\">+</span> appid\n    key <span class=\"token operator\">=</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'Records'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'cos'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'cosObject'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'key'</span><span class=\"token punctuation\">]</span>\n    key <span class=\"token operator\">=</span> key<span class=\"token punctuation\">.</span>replace<span class=\"token punctuation\">(</span><span class=\"token string\">'/'</span> <span class=\"token operator\">+</span> <span class=\"token builtin\">str</span><span class=\"token punctuation\">(</span>appid<span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> <span class=\"token string\">'/'</span> <span class=\"token operator\">+</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'Records'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'cos'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'cosBucket'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'name'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">+</span> <span class=\"token string\">'/'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">''</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\n    logger<span class=\"token punctuation\">.</span>info<span class=\"token punctuation\">(</span><span class=\"token string\">\"Key is \"</span> <span class=\"token operator\">+</span> key<span class=\"token punctuation\">)</span>\n    middle_bucket <span class=\"token operator\">=</span> middle_stage_bucket <span class=\"token operator\">+</span> <span class=\"token string\">'-'</span> <span class=\"token operator\">+</span> appid\n    middle_file_key <span class=\"token operator\">=</span> <span class=\"token string\">'/'</span> <span class=\"token operator\">+</span> <span class=\"token string\">'middle_'</span> <span class=\"token operator\">+</span> key<span class=\"token punctuation\">.</span>split<span class=\"token punctuation\">(</span><span class=\"token string\">'/'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">[</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span>\n    <span class=\"token keyword\">return</span> do_mapping<span class=\"token punctuation\">(</span>cos_client<span class=\"token punctuation\">,</span> bucket<span class=\"token punctuation\">,</span> key<span class=\"token punctuation\">,</span> middle_bucket<span class=\"token punctuation\">,</span> middle_file_key<span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">main_handler</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">,</span> context<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    logger<span class=\"token punctuation\">.</span>info<span class=\"token punctuation\">(</span><span class=\"token string\">\"start main handler\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">if</span> <span class=\"token string\">\"Records\"</span> <span class=\"token keyword\">not</span> <span class=\"token keyword\">in</span> event<span class=\"token punctuation\">.</span>keys<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span><span class=\"token string\">\"errorMsg\"</span><span class=\"token punctuation\">:</span> <span class=\"token string\">\"event is not come from cos\"</span><span class=\"token punctuation\">}</span>\n    secret_id <span class=\"token operator\">=</span> <span class=\"token string\">\"\"</span>\n    secret_key <span class=\"token operator\">=</span> <span class=\"token string\">\"\"</span>\n    config <span class=\"token operator\">=</span> CosConfig<span class=\"token punctuation\">(</span>Region<span class=\"token operator\">=</span>region<span class=\"token punctuation\">,</span> SecretId<span class=\"token operator\">=</span>secret_id<span class=\"token punctuation\">,</span> SecretKey<span class=\"token operator\">=</span>secret_key<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">)</span>\n    cos_client <span class=\"token operator\">=</span> CosS3Client<span class=\"token punctuation\">(</span>config<span class=\"token punctuation\">)</span>\n    start_time <span class=\"token operator\">=</span> datetime<span class=\"token punctuation\">.</span>datetime<span class=\"token punctuation\">.</span>now<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    res <span class=\"token operator\">=</span> map_caller<span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">,</span> context<span class=\"token punctuation\">,</span> cos_client<span class=\"token punctuation\">)</span>\n    end_time <span class=\"token operator\">=</span> datetime<span class=\"token punctuation\">.</span>datetime<span class=\"token punctuation\">.</span>now<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"data mapping duration: \"</span> <span class=\"token operator\">+</span> <span class=\"token builtin\">str</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>end_time <span class=\"token operator\">-</span> start_time<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>microseconds <span class=\"token operator\">/</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> <span class=\"token string\">\"ms\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">if</span> res <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> <span class=\"token string\">\"Data mapping SUCCESS\"</span>\n    <span class=\"token keyword\">else</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> <span class=\"token string\">\"Data mapping FAILED\"</span></code></pre></div>\n<p>同样的方法，建立 <code class=\"language-text\">reducer.py</code> 文件，编写 Reducer 逻辑，代码如下：</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"85319457741513060000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`# -*- coding: utf8 -*-\nfrom qcloud_cos_v5 import CosConfig\nfrom qcloud_cos_v5 import CosS3Client\nfrom qcloud_cos_v5 import CosServiceError\nfrom operator import itemgetter\nimport os\nimport sys\nimport datetime\nimport logging\nregion = u'ap-guangzhou'  # 根据实际情况，修改地域\nresult_bucket = u'destmr'  # 根据实际情况，修改bucket名\nlogging.basicConfig(level=logging.INFO, stream=sys.stdout)\nlogger = logging.getLogger()\nlogger.setLevel(level=logging.INFO)\ndef delete_file_folder(src):\n    if os.path.isfile(src):\n        try:\n            os.remove(src)\n        except:\n            pass\n    elif os.path.isdir(src):\n        for item in os.listdir(src):\n            itemsrc = os.path.join(src, item)\n            delete_file_folder(itemsrc)\n        try:\n            os.rmdir(src)\n        except:\n            pass\ndef download_file(cos_client, bucket, key, download_path):\n    logger.info(&quot;Get from [%s] to download file [%s]&quot; % (bucket, key))\n    try:\n        response = cos_client.get_object(Bucket=bucket, Key=key, )\n        response['Body'].get_stream_to_file(download_path)\n    except CosServiceError as e:\n        print(e.get_error_code())\n        print(e.get_error_msg())\n        return -1\n    return 0\ndef upload_file(cos_client, bucket, key, local_file_path):\n    logger.info(&quot;Start to upload file to cos&quot;)\n    try:\n        response = cos_client.put_object_from_local_file(\n            Bucket=bucket,\n            LocalFilePath=local_file_path,\n            Key='{}'.format(key))\n    except CosServiceError as e:\n        print(e.get_error_code())\n        print(e.get_error_msg())\n        return -1\n    logger.info(&quot;Upload data map file [%s] Success&quot; % key)\n    return 0\ndef qcloud_reducer(cos_client, bucket, key, result_bucket, result_key):\n    word2count = {}\n    src_file_path = u'/tmp/' + key.split('/')[-1]\n    result_file_path = u'/tmp/' + u'result_' + key.split('/')[-1]\n    download_ret = download_file(cos_client, bucket, key, src_file_path)\n    if download_ret == 0:\n        map_file = open(src_file_path, 'r')\n        result_file = open(result_file_path, 'w')\n        for line in map_file:\n            line = line.strip()\n            word, count = line.split('\\t', 1)\n            try:\n                count = int(count)\n                word2count[word] = word2count.get(word, 0) + count\n            except ValueError:\n                logger.error(&quot;error value: %s, current line: %s&quot; % (ValueError, line))\n                continue\n        map_file.close()\n        delete_file_folder(src_file_path)\n    sorted_word2count = sorted(word2count.items(), key=itemgetter(1))[::-1]\n    for wordcount in sorted_word2count:\n        res = '%s\\t%s' % (wordcount[0], wordcount[1])\n        result_file.write(res)\n        result_file.write('\\n')\n    result_file.close()\n    upload_ret = upload_file(cos_client, result_bucket, result_key, result_file_path)\n    delete_file_folder(result_file_path)\n    return upload_ret\ndef reduce_caller(event, context, cos_client):\n    appid = event['Records'][0]['cos']['cosBucket']['appid']\n    bucket = event['Records'][0]['cos']['cosBucket']['name'] + '-' + appid\n    key = event['Records'][0]['cos']['cosObject']['key']\n    key = key.replace('/' + str(appid) + '/' + event['Records'][0]['cos']['cosBucket']['name'] + '/', '', 1)\n    logger.info(&quot;Key is &quot; + key)\n    res_bucket = result_bucket + '-' + appid\n    result_key = '/' + 'result_' + key.split('/')[-1]\n    return qcloud_reducer(cos_client, bucket, key, res_bucket, result_key)\ndef main_handler(event, context):\n    logger.info(&quot;start main handler&quot;)\n    if &quot;Records&quot; not in event.keys():\n        return {&quot;errorMsg&quot;: &quot;event is not come from cos&quot;}\n    secret_id = &quot;SecretId&quot;\n    secret_key = &quot;SecretKey&quot;\n    config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, )\n    cos_client = CosS3Client(config)\n    start_time = datetime.datetime.now()\n    res = reduce_caller(event, context, cos_client)\n    end_time = datetime.datetime.now()\n    print(&quot;data reducing duration: &quot; + str((end_time - start_time).microseconds / 1000) + &quot;ms&quot;)\n    if res == 0:\n        return &quot;Data reducing SUCCESS&quot;\n    else:\n        return &quot;Data reducing FAILED&quot;`, `85319457741513060000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token comment\"># -*- coding: utf8 -*-</span>\n<span class=\"token keyword\">from</span> qcloud_cos_v5 <span class=\"token keyword\">import</span> CosConfig\n<span class=\"token keyword\">from</span> qcloud_cos_v5 <span class=\"token keyword\">import</span> CosS3Client\n<span class=\"token keyword\">from</span> qcloud_cos_v5 <span class=\"token keyword\">import</span> CosServiceError\n<span class=\"token keyword\">from</span> operator <span class=\"token keyword\">import</span> itemgetter\n<span class=\"token keyword\">import</span> os\n<span class=\"token keyword\">import</span> sys\n<span class=\"token keyword\">import</span> datetime\n<span class=\"token keyword\">import</span> logging\nregion <span class=\"token operator\">=</span> <span class=\"token string\">u'ap-guangzhou'</span>  <span class=\"token comment\"># 根据实际情况，修改地域</span>\nresult_bucket <span class=\"token operator\">=</span> <span class=\"token string\">u'destmr'</span>  <span class=\"token comment\"># 根据实际情况，修改bucket名</span>\nlogging<span class=\"token punctuation\">.</span>basicConfig<span class=\"token punctuation\">(</span>level<span class=\"token operator\">=</span>logging<span class=\"token punctuation\">.</span>INFO<span class=\"token punctuation\">,</span> stream<span class=\"token operator\">=</span>sys<span class=\"token punctuation\">.</span>stdout<span class=\"token punctuation\">)</span>\nlogger <span class=\"token operator\">=</span> logging<span class=\"token punctuation\">.</span>getLogger<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\nlogger<span class=\"token punctuation\">.</span>setLevel<span class=\"token punctuation\">(</span>level<span class=\"token operator\">=</span>logging<span class=\"token punctuation\">.</span>INFO<span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">delete_file_folder</span><span class=\"token punctuation\">(</span>src<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">if</span> os<span class=\"token punctuation\">.</span>path<span class=\"token punctuation\">.</span>isfile<span class=\"token punctuation\">(</span>src<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">try</span><span class=\"token punctuation\">:</span>\n            os<span class=\"token punctuation\">.</span>remove<span class=\"token punctuation\">(</span>src<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">except</span><span class=\"token punctuation\">:</span>\n            <span class=\"token keyword\">pass</span>\n    <span class=\"token keyword\">elif</span> os<span class=\"token punctuation\">.</span>path<span class=\"token punctuation\">.</span>isdir<span class=\"token punctuation\">(</span>src<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">for</span> item <span class=\"token keyword\">in</span> os<span class=\"token punctuation\">.</span>listdir<span class=\"token punctuation\">(</span>src<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n            itemsrc <span class=\"token operator\">=</span> os<span class=\"token punctuation\">.</span>path<span class=\"token punctuation\">.</span>join<span class=\"token punctuation\">(</span>src<span class=\"token punctuation\">,</span> item<span class=\"token punctuation\">)</span>\n            delete_file_folder<span class=\"token punctuation\">(</span>itemsrc<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">try</span><span class=\"token punctuation\">:</span>\n            os<span class=\"token punctuation\">.</span>rmdir<span class=\"token punctuation\">(</span>src<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">except</span><span class=\"token punctuation\">:</span>\n            <span class=\"token keyword\">pass</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">download_file</span><span class=\"token punctuation\">(</span>cos_client<span class=\"token punctuation\">,</span> bucket<span class=\"token punctuation\">,</span> key<span class=\"token punctuation\">,</span> download_path<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    logger<span class=\"token punctuation\">.</span>info<span class=\"token punctuation\">(</span><span class=\"token string\">\"Get from [%s] to download file [%s]\"</span> <span class=\"token operator\">%</span> <span class=\"token punctuation\">(</span>bucket<span class=\"token punctuation\">,</span> key<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">try</span><span class=\"token punctuation\">:</span>\n        response <span class=\"token operator\">=</span> cos_client<span class=\"token punctuation\">.</span>get_object<span class=\"token punctuation\">(</span>Bucket<span class=\"token operator\">=</span>bucket<span class=\"token punctuation\">,</span> Key<span class=\"token operator\">=</span>key<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">)</span>\n        response<span class=\"token punctuation\">[</span><span class=\"token string\">'Body'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span>get_stream_to_file<span class=\"token punctuation\">(</span>download_path<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">except</span> CosServiceError <span class=\"token keyword\">as</span> e<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>get_error_code<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>get_error_msg<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> <span class=\"token operator\">-</span><span class=\"token number\">1</span>\n    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">upload_file</span><span class=\"token punctuation\">(</span>cos_client<span class=\"token punctuation\">,</span> bucket<span class=\"token punctuation\">,</span> key<span class=\"token punctuation\">,</span> local_file_path<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    logger<span class=\"token punctuation\">.</span>info<span class=\"token punctuation\">(</span><span class=\"token string\">\"Start to upload file to cos\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">try</span><span class=\"token punctuation\">:</span>\n        response <span class=\"token operator\">=</span> cos_client<span class=\"token punctuation\">.</span>put_object_from_local_file<span class=\"token punctuation\">(</span>\n            Bucket<span class=\"token operator\">=</span>bucket<span class=\"token punctuation\">,</span>\n            LocalFilePath<span class=\"token operator\">=</span>local_file_path<span class=\"token punctuation\">,</span>\n            Key<span class=\"token operator\">=</span><span class=\"token string\">'{}'</span><span class=\"token punctuation\">.</span><span class=\"token builtin\">format</span><span class=\"token punctuation\">(</span>key<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">except</span> CosServiceError <span class=\"token keyword\">as</span> e<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>get_error_code<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>get_error_msg<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> <span class=\"token operator\">-</span><span class=\"token number\">1</span>\n    logger<span class=\"token punctuation\">.</span>info<span class=\"token punctuation\">(</span><span class=\"token string\">\"Upload data map file [%s] Success\"</span> <span class=\"token operator\">%</span> key<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">qcloud_reducer</span><span class=\"token punctuation\">(</span>cos_client<span class=\"token punctuation\">,</span> bucket<span class=\"token punctuation\">,</span> key<span class=\"token punctuation\">,</span> result_bucket<span class=\"token punctuation\">,</span> result_key<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    word2count <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span>\n    src_file_path <span class=\"token operator\">=</span> <span class=\"token string\">u'/tmp/'</span> <span class=\"token operator\">+</span> key<span class=\"token punctuation\">.</span>split<span class=\"token punctuation\">(</span><span class=\"token string\">'/'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">[</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span>\n    result_file_path <span class=\"token operator\">=</span> <span class=\"token string\">u'/tmp/'</span> <span class=\"token operator\">+</span> <span class=\"token string\">u'result_'</span> <span class=\"token operator\">+</span> key<span class=\"token punctuation\">.</span>split<span class=\"token punctuation\">(</span><span class=\"token string\">'/'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">[</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span>\n    download_ret <span class=\"token operator\">=</span> download_file<span class=\"token punctuation\">(</span>cos_client<span class=\"token punctuation\">,</span> bucket<span class=\"token punctuation\">,</span> key<span class=\"token punctuation\">,</span> src_file_path<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">if</span> download_ret <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">:</span>\n        map_file <span class=\"token operator\">=</span> <span class=\"token builtin\">open</span><span class=\"token punctuation\">(</span>src_file_path<span class=\"token punctuation\">,</span> <span class=\"token string\">'r'</span><span class=\"token punctuation\">)</span>\n        result_file <span class=\"token operator\">=</span> <span class=\"token builtin\">open</span><span class=\"token punctuation\">(</span>result_file_path<span class=\"token punctuation\">,</span> <span class=\"token string\">'w'</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">for</span> line <span class=\"token keyword\">in</span> map_file<span class=\"token punctuation\">:</span>\n            line <span class=\"token operator\">=</span> line<span class=\"token punctuation\">.</span>strip<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n            word<span class=\"token punctuation\">,</span> count <span class=\"token operator\">=</span> line<span class=\"token punctuation\">.</span>split<span class=\"token punctuation\">(</span><span class=\"token string\">'\\t'</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\n            <span class=\"token keyword\">try</span><span class=\"token punctuation\">:</span>\n                count <span class=\"token operator\">=</span> <span class=\"token builtin\">int</span><span class=\"token punctuation\">(</span>count<span class=\"token punctuation\">)</span>\n                word2count<span class=\"token punctuation\">[</span>word<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> word2count<span class=\"token punctuation\">.</span>get<span class=\"token punctuation\">(</span>word<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> count\n            <span class=\"token keyword\">except</span> ValueError<span class=\"token punctuation\">:</span>\n                logger<span class=\"token punctuation\">.</span>error<span class=\"token punctuation\">(</span><span class=\"token string\">\"error value: %s, current line: %s\"</span> <span class=\"token operator\">%</span> <span class=\"token punctuation\">(</span>ValueError<span class=\"token punctuation\">,</span> line<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n                <span class=\"token keyword\">continue</span>\n        map_file<span class=\"token punctuation\">.</span>close<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        delete_file_folder<span class=\"token punctuation\">(</span>src_file_path<span class=\"token punctuation\">)</span>\n    sorted_word2count <span class=\"token operator\">=</span> <span class=\"token builtin\">sorted</span><span class=\"token punctuation\">(</span>word2count<span class=\"token punctuation\">.</span>items<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> key<span class=\"token operator\">=</span>itemgetter<span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">:</span><span class=\"token punctuation\">:</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span>\n    <span class=\"token keyword\">for</span> wordcount <span class=\"token keyword\">in</span> sorted_word2count<span class=\"token punctuation\">:</span>\n        res <span class=\"token operator\">=</span> <span class=\"token string\">'%s\\t%s'</span> <span class=\"token operator\">%</span> <span class=\"token punctuation\">(</span>wordcount<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> wordcount<span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n        result_file<span class=\"token punctuation\">.</span>write<span class=\"token punctuation\">(</span>res<span class=\"token punctuation\">)</span>\n        result_file<span class=\"token punctuation\">.</span>write<span class=\"token punctuation\">(</span><span class=\"token string\">'\\n'</span><span class=\"token punctuation\">)</span>\n    result_file<span class=\"token punctuation\">.</span>close<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    upload_ret <span class=\"token operator\">=</span> upload_file<span class=\"token punctuation\">(</span>cos_client<span class=\"token punctuation\">,</span> result_bucket<span class=\"token punctuation\">,</span> result_key<span class=\"token punctuation\">,</span> result_file_path<span class=\"token punctuation\">)</span>\n    delete_file_folder<span class=\"token punctuation\">(</span>result_file_path<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> upload_ret\n<span class=\"token keyword\">def</span> <span class=\"token function\">reduce_caller</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">,</span> context<span class=\"token punctuation\">,</span> cos_client<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    appid <span class=\"token operator\">=</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'Records'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'cos'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'cosBucket'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'appid'</span><span class=\"token punctuation\">]</span>\n    bucket <span class=\"token operator\">=</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'Records'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'cos'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'cosBucket'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'name'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">+</span> <span class=\"token string\">'-'</span> <span class=\"token operator\">+</span> appid\n    key <span class=\"token operator\">=</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'Records'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'cos'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'cosObject'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'key'</span><span class=\"token punctuation\">]</span>\n    key <span class=\"token operator\">=</span> key<span class=\"token punctuation\">.</span>replace<span class=\"token punctuation\">(</span><span class=\"token string\">'/'</span> <span class=\"token operator\">+</span> <span class=\"token builtin\">str</span><span class=\"token punctuation\">(</span>appid<span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> <span class=\"token string\">'/'</span> <span class=\"token operator\">+</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'Records'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'cos'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'cosBucket'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'name'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">+</span> <span class=\"token string\">'/'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">''</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\n    logger<span class=\"token punctuation\">.</span>info<span class=\"token punctuation\">(</span><span class=\"token string\">\"Key is \"</span> <span class=\"token operator\">+</span> key<span class=\"token punctuation\">)</span>\n    res_bucket <span class=\"token operator\">=</span> result_bucket <span class=\"token operator\">+</span> <span class=\"token string\">'-'</span> <span class=\"token operator\">+</span> appid\n    result_key <span class=\"token operator\">=</span> <span class=\"token string\">'/'</span> <span class=\"token operator\">+</span> <span class=\"token string\">'result_'</span> <span class=\"token operator\">+</span> key<span class=\"token punctuation\">.</span>split<span class=\"token punctuation\">(</span><span class=\"token string\">'/'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">[</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span>\n    <span class=\"token keyword\">return</span> qcloud_reducer<span class=\"token punctuation\">(</span>cos_client<span class=\"token punctuation\">,</span> bucket<span class=\"token punctuation\">,</span> key<span class=\"token punctuation\">,</span> res_bucket<span class=\"token punctuation\">,</span> result_key<span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">main_handler</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">,</span> context<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    logger<span class=\"token punctuation\">.</span>info<span class=\"token punctuation\">(</span><span class=\"token string\">\"start main handler\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">if</span> <span class=\"token string\">\"Records\"</span> <span class=\"token keyword\">not</span> <span class=\"token keyword\">in</span> event<span class=\"token punctuation\">.</span>keys<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span><span class=\"token string\">\"errorMsg\"</span><span class=\"token punctuation\">:</span> <span class=\"token string\">\"event is not come from cos\"</span><span class=\"token punctuation\">}</span>\n    secret_id <span class=\"token operator\">=</span> <span class=\"token string\">\"SecretId\"</span>\n    secret_key <span class=\"token operator\">=</span> <span class=\"token string\">\"SecretKey\"</span>\n    config <span class=\"token operator\">=</span> CosConfig<span class=\"token punctuation\">(</span>Region<span class=\"token operator\">=</span>region<span class=\"token punctuation\">,</span> SecretId<span class=\"token operator\">=</span>secret_id<span class=\"token punctuation\">,</span> SecretKey<span class=\"token operator\">=</span>secret_key<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">)</span>\n    cos_client <span class=\"token operator\">=</span> CosS3Client<span class=\"token punctuation\">(</span>config<span class=\"token punctuation\">)</span>\n    start_time <span class=\"token operator\">=</span> datetime<span class=\"token punctuation\">.</span>datetime<span class=\"token punctuation\">.</span>now<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    res <span class=\"token operator\">=</span> reduce_caller<span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">,</span> context<span class=\"token punctuation\">,</span> cos_client<span class=\"token punctuation\">)</span>\n    end_time <span class=\"token operator\">=</span> datetime<span class=\"token punctuation\">.</span>datetime<span class=\"token punctuation\">.</span>now<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"data reducing duration: \"</span> <span class=\"token operator\">+</span> <span class=\"token builtin\">str</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>end_time <span class=\"token operator\">-</span> start_time<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>microseconds <span class=\"token operator\">/</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> <span class=\"token string\">\"ms\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">if</span> res <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> <span class=\"token string\">\"Data reducing SUCCESS\"</span>\n    <span class=\"token keyword\">else</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> <span class=\"token string\">\"Data reducing FAILED\"</span></code></pre></div>\n<h2 id=\"部署与测试\"><a href=\"#%E9%83%A8%E7%BD%B2%E4%B8%8E%E6%B5%8B%E8%AF%95\" aria-label=\"部署与测试 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>部署与测试</h2>\n<p>遵循 Serverless Framework 的 <code class=\"language-text\">yaml</code> 规范，编写 <code class=\"language-text\">serveerless.yaml</code>:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"1046616216019757800\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`WordCountMapper:\n  component: &quot;@serverless/tencent-scf&quot;\n  inputs:\n    name: mapper\n    codeUri: ./code\n    handler: index.main_handler\n    runtime: Python3.6\n    region: ap-guangzhou\n    description: 网站监控\n    memorySize: 64\n    timeout: 20\n    events:\n      - cos:\n          name: srcmr-1256773370.cos.ap-guangzhou.myqcloud.com\n          parameters:\n            bucket: srcmr-1256773370.cos.ap-guangzhou.myqcloud.com\n            filter:\n              prefix: ''\n              suffix: ''\n            events: cos:ObjectCreated:*\n            enable: true\n\nWordCountReducer:\n  component: &quot;@serverless/tencent-scf&quot;\n  inputs:\n    name: reducer\n    codeUri: ./code\n    handler: index.main_handler\n    runtime: Python3.6\n    region: ap-guangzhou\n    description: 网站监控\n    memorySize: 64\n    timeout: 20\n    events:\n      - cos:\n          name: middlestagebucket-1256773370.cos.ap-guangzhou.myqcloud.com\n          parameters:\n            bucket: middlestagebucket-1256773370.cos.ap-guangzhou.myqcloud.com\n            filter:\n              prefix: ''\n              suffix: ''\n            events: cos:ObjectCreated:*\n            enable: true`, `1046616216019757800`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"yaml\"><pre class=\"language-yaml\"><code class=\"language-yaml\"><span class=\"token key atrule\">WordCountMapper</span><span class=\"token punctuation\">:</span>\n  <span class=\"token key atrule\">component</span><span class=\"token punctuation\">:</span> <span class=\"token string\">\"@serverless/tencent-scf\"</span>\n  <span class=\"token key atrule\">inputs</span><span class=\"token punctuation\">:</span>\n    <span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> mapper\n    <span class=\"token key atrule\">codeUri</span><span class=\"token punctuation\">:</span> ./code\n    <span class=\"token key atrule\">handler</span><span class=\"token punctuation\">:</span> index.main_handler\n    <span class=\"token key atrule\">runtime</span><span class=\"token punctuation\">:</span> Python3.6\n    <span class=\"token key atrule\">region</span><span class=\"token punctuation\">:</span> ap<span class=\"token punctuation\">-</span>guangzhou\n    <span class=\"token key atrule\">description</span><span class=\"token punctuation\">:</span> 网站监控\n    <span class=\"token key atrule\">memorySize</span><span class=\"token punctuation\">:</span> <span class=\"token number\">64</span>\n    <span class=\"token key atrule\">timeout</span><span class=\"token punctuation\">:</span> <span class=\"token number\">20</span>\n    <span class=\"token key atrule\">events</span><span class=\"token punctuation\">:</span>\n      <span class=\"token punctuation\">-</span> <span class=\"token key atrule\">cos</span><span class=\"token punctuation\">:</span>\n          <span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> srcmr<span class=\"token punctuation\">-</span>1256773370.cos.ap<span class=\"token punctuation\">-</span>guangzhou.myqcloud.com\n          <span class=\"token key atrule\">parameters</span><span class=\"token punctuation\">:</span>\n            <span class=\"token key atrule\">bucket</span><span class=\"token punctuation\">:</span> srcmr<span class=\"token punctuation\">-</span>1256773370.cos.ap<span class=\"token punctuation\">-</span>guangzhou.myqcloud.com\n            <span class=\"token key atrule\">filter</span><span class=\"token punctuation\">:</span>\n              <span class=\"token key atrule\">prefix</span><span class=\"token punctuation\">:</span> <span class=\"token string\">''</span>\n              <span class=\"token key atrule\">suffix</span><span class=\"token punctuation\">:</span> <span class=\"token string\">''</span>\n            <span class=\"token key atrule\">events</span><span class=\"token punctuation\">:</span> cos<span class=\"token punctuation\">:</span>ObjectCreated<span class=\"token punctuation\">:</span>*\n            <span class=\"token key atrule\">enable</span><span class=\"token punctuation\">:</span> <span class=\"token boolean important\">true</span>\n\n<span class=\"token key atrule\">WordCountReducer</span><span class=\"token punctuation\">:</span>\n  <span class=\"token key atrule\">component</span><span class=\"token punctuation\">:</span> <span class=\"token string\">\"@serverless/tencent-scf\"</span>\n  <span class=\"token key atrule\">inputs</span><span class=\"token punctuation\">:</span>\n    <span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> reducer\n    <span class=\"token key atrule\">codeUri</span><span class=\"token punctuation\">:</span> ./code\n    <span class=\"token key atrule\">handler</span><span class=\"token punctuation\">:</span> index.main_handler\n    <span class=\"token key atrule\">runtime</span><span class=\"token punctuation\">:</span> Python3.6\n    <span class=\"token key atrule\">region</span><span class=\"token punctuation\">:</span> ap<span class=\"token punctuation\">-</span>guangzhou\n    <span class=\"token key atrule\">description</span><span class=\"token punctuation\">:</span> 网站监控\n    <span class=\"token key atrule\">memorySize</span><span class=\"token punctuation\">:</span> <span class=\"token number\">64</span>\n    <span class=\"token key atrule\">timeout</span><span class=\"token punctuation\">:</span> <span class=\"token number\">20</span>\n    <span class=\"token key atrule\">events</span><span class=\"token punctuation\">:</span>\n      <span class=\"token punctuation\">-</span> <span class=\"token key atrule\">cos</span><span class=\"token punctuation\">:</span>\n          <span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> middlestagebucket<span class=\"token punctuation\">-</span>1256773370.cos.ap<span class=\"token punctuation\">-</span>guangzhou.myqcloud.com\n          <span class=\"token key atrule\">parameters</span><span class=\"token punctuation\">:</span>\n            <span class=\"token key atrule\">bucket</span><span class=\"token punctuation\">:</span> middlestagebucket<span class=\"token punctuation\">-</span>1256773370.cos.ap<span class=\"token punctuation\">-</span>guangzhou.myqcloud.com\n            <span class=\"token key atrule\">filter</span><span class=\"token punctuation\">:</span>\n              <span class=\"token key atrule\">prefix</span><span class=\"token punctuation\">:</span> <span class=\"token string\">''</span>\n              <span class=\"token key atrule\">suffix</span><span class=\"token punctuation\">:</span> <span class=\"token string\">''</span>\n            <span class=\"token key atrule\">events</span><span class=\"token punctuation\">:</span> cos<span class=\"token punctuation\">:</span>ObjectCreated<span class=\"token punctuation\">:</span>*\n            <span class=\"token key atrule\">enable</span><span class=\"token punctuation\">:</span> <span class=\"token boolean important\">true</span></code></pre></div>\n<p>完成之后，通过 <code class=\"language-text\">sls --debug</code> 指令进行部署。部署成功之后，进行基本的测试：</p>\n<ol>\n<li>准备一个英文文档:\n<img src=\"https://img.serverlesscloud.cn/202058/2-7-3.png\"></li>\n<li>登录腾讯云后台，打开我们最初建立的存储桶：srcmr，并上传该文件;</li>\n<li>上传成功之后，稍等片刻即可看到 Reducer 程序已经在 Mapper 执行之后，产出日志:\n<img src=\"https://img.serverlesscloud.cn/202058/2-7-4.png\"></li>\n</ol>\n<p>此时，我们打开结果存储桶，查看结果:\n<img src=\"https://img.serverlesscloud.cn/202058/2-7-5.png\"></p>\n<p>现在，我们就完成了简单的词频统计功能。</p>\n<h2 id=\"总结\"><a href=\"#%E6%80%BB%E7%BB%93\" aria-label=\"总结 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>总结</h2>\n<p>Serverless 架构相是适用于大数据处理的。在腾讯云官网，我们也可以看到其关于数据 ETL 处理的场景描述：</p>\n<blockquote>\n<p>一些数据处理系统中，常常需要周期性/计划性地处理庞大的数据量。例如：证券公司每 12 小时统计一次该时段的交易情况并整理出该时段交易量 top 5，每天处理一遍秒杀网站的交易流日志获取因售罄而导致的错误从而分析商品热度和趋势等。云函数近乎无限扩容的能力可以使您轻松地进行大容量数据的计算。我们利用云函数可以对源数据并发执行多个 mapper 和 reducer 函数，在短时间内完成工作；相比传统的工作方式，使用云函数更能避免资源的闲置浪费从而节省资金。</p>\n</blockquote>\n<p>本实例中，有一键部署多个函数的操作。在实际生产中，每个项目都不会是单个函数单打独斗的，而是多个函数组合应用，形成一个 Service 体系，所以一键部署多个函数就显得尤为重要。通过本实例，希望读者可以对 Serverless 架构的应用场景有更多的了解，并且能有所启发，将云函数和不同触发器进行组合，应用在自身业务中。</p>\n<hr>\n<div id='scf-deploy-iframe-or-md'></div>\n<hr>\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":"<ul>\n<li><a href=\"/best-practice/2020-05-08-wordcount/#%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80\">理论基础</a></li>\n<li><a href=\"/best-practice/2020-05-08-wordcount/#%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0\">功能实现</a></li>\n<li><a href=\"/best-practice/2020-05-08-wordcount/#%E9%83%A8%E7%BD%B2%E4%B8%8E%E6%B5%8B%E8%AF%95\">部署与测试</a></li>\n<li><a href=\"/best-practice/2020-05-08-wordcount/#%E6%80%BB%E7%BB%93\">总结</a></li>\n</ul>"},"previousBlog":{"id":"2ed40490-e6db-51f2-a0a0-8fa52c3488d7","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020511/1589207418781-ZalNtxgQAC_small.jpg","authors":["Anycodes"],"categories":["best-practice"],"date":"2020-05-09T00:00:00.000Z","title":"Serverless 与 Websocket 的聊天工具","description":"传统业务实现 Websocket 并不难，然而函数计算基本上都是事件驱动，不支持长链接操作。如果将函数计算与 API 网关结合，是否可以有 Websocket 的实现方案呢？","authorslink":["https://zhuanlan.zhihu.com/ServerlessGo"],"translators":null,"translatorslink":null,"tags":["Serverless","Websocket"],"keywords":"Serverless 多环境配置,Serverless 管理环境,Serverless配置方案","outdated":true},"wordCount":{"words":263,"sentences":43,"paragraphs":43},"fileAbsolutePath":"/opt/build/repo/content/best-practice/2020-05-09-serverless-websocket.md","fields":{"slug":"/best-practice/2020-05-09-serverless-websocket/","keywords":["java","python","serverless","函数计算","云函数","secret","网关","item","客户端","Conf","bucket","retmsg","os"]}},"nextBlog":{"id":"d1450693-7418-5532-8bd4-4fe42f275bdf","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020512/1589274622959-J2kmfdLCPpX436WYvs0D.jpg","authors":["Anycodes"],"categories":["best-practice"],"date":"2020-05-05T00:00:00.000Z","title":"Serverless 与人工智能实现微信公众号的智能服务","description":"一般情况下，想给公众号增加更多的功能，需要我们在服务器上搭建后台服务。那么在 Serverless 架构下，能否更简单地实现相同的后台服务呢？","authorslink":["https://zhuanlan.zhihu.com/ServerlessGo"],"translators":null,"translatorslink":null,"tags":["Serverless","人工智能"],"keywords":"Serverless 多环境配置,Serverless 管理环境,Serverless配置方案","outdated":true},"wordCount":{"words":519,"sentences":119,"paragraphs":119},"fileAbsolutePath":"/opt/build/repo/content/best-practice/2020-05-05-ai-wechat.md","fields":{"slug":"/best-practice/2020-05-05-ai-wechat/","keywords":["python","serverless","函数计算","函数计算服务","event","json","media","time"]}}},"pageContext":{"isCreatedByStatefulCreatePages":false,"blogId":"249242aa-c81b-5ff8-9553-90e8792af73e","previousBlogId":"2ed40490-e6db-51f2-a0a0-8fa52c3488d7","nextBlogId":"d1450693-7418-5532-8bd4-4fe42f275bdf"}}}