天天看點

使用騰訊雲無伺服器雲函數(SCF)分析天氣資料

無伺服器雲函數(SCF)是騰訊雲提供的Serverless執行環境,也是國内首款FaaS(Function as a Service,函數即服務) 産品。其核心理念是讓使用者将重心放在業務的邏輯實作上,而不用關心底層的運維包括伺服器、存儲、網絡、自動擴縮容、負載均衡、代碼部署等問題。

歡迎大家前往雲+社群,擷取更多騰訊海量技術實踐幹貨哦~

作者:李想

雲函數既然以函數這兩個字來命名,其應用場景也是跟函數是極為相似的,即對一段資料執行函數計算然後進行輸出。騰訊雲雲函數提供了各類觸發器來控制函數的執行條件,代碼完全由事件觸發,平台根據請求自動平行調整服務資源,是以SCF特别适合需要在某些情景下需要進行資料處理的場合。例如使用者上傳檔案之後過濾是否有違規字段,或者使用者上傳視訊檔案之後進行轉碼等。

騰訊雲的SCF底層也是基于容器進行建構,使用者的代碼會加載到容器内進行執行,是以效率和性能方面能夠得到保證。同時使用VPC和Unix Socket來隔離使用者環境與管理環境,保證了SCF使用的安全性。函數可自動在每個地域中随機地選擇可用區來運作,免除單可用區運作的故障風險。根據事件請求數量,雲函數将自動橫向擴容/縮容,無需使用者自行配置擴縮容條件,擴容數量理論上沒有上限。

提到雲函數SCF也順便提一下騰訊雲将要推出的另外一個産品--批量計算。從本質上來講批量計算和雲函數都是将業務邏輯代碼進行抽象而提供統一的入口供使用者使用,但是兩者在使用場景上也有一些差別。批量計算主要是為了處理大資料而設計的,其最關鍵的技術是可以對原始資料進行分片而将分片的資料配置設定到不同的節點進行處理,而雲函數本身盡管可以并發執行,但是其處理的一般為流資料,資料量相對較小,耗時也相對較短。舉個例子,如果我們需要對使用者上傳的檔案進行實時處理,建議使用雲函數SCF,而如果需要将硬碟上現有的比如幾個T的使用者資料進行處理,建議使用批量計算進行分批處理。

我們就以一個真實的資料來把玩一下騰訊雲無伺服器雲函數,讓大家能更好的了解雲函數。資料來源于美國NCDC的天氣資料:ftp://ftp.ncdc.noaa.gov/pub/data/noaa/isd-lite/

裡面記錄了從1900年至今所有監控點每天的監控資料,我們以2017年的資料為例(ftp://ftp.ncdc.noaa.gov/pub/data/noaa/isd-lite/2017/),裡面的每一個.gz檔案代表一個監控點全年的監控資料。

010010-99999-2017.gz 解壓之後的檔案内容如下:

2017 01 01 22 -48 -97 10205 340 60 -9999 -9999 -9999

2017 01 01 23 -47 -99 10202 346 55 -9999 -9999 -9999

2017 01 02 00 -49 -93 10190 330 90 6 -9999 4

2017 01 02 01 -47 -96 10190 346 72 -9999 -9999 -9999

2017 01 02 02 -50 -98 10189 320 40 -9999 -9999 -9999

2017 01 02 03 -47 -95 10185 328 30 -9999 -9999 -9999

2017 01 02 04 -52 -95 10176 320 20 -9999 -9999 -9999

2017 01 02 05 -62 -97 10163 310 20 -9999 -9999 -9999

2017 01 02 06 -57 -91 10150 260 20 8 -9999 -9999

2017 01 02 07 -46 -86 10141 230 30 -9999 -9999 -9999

2017 01 02 08 -37 -72 10131 206 45 -9999 -9999 -9999 .....

NCDC官方也給出了檔案格式說明,1-13位記錄的是觀測時間,14-19位記錄了觀測的溫度(以10倍的攝氏度進行記錄)。

Field 1: Pos 1-4, Length 4: Observation Year Year of observation,

rounded to nearest whole hourField 2: Pos 6-7, Length 2: Observation Month Month of observation,

rounded to nearest whole hourField 3: Pos 9-11, Length 2: Observation Day Day of observation,

rounded to nearest whole hourField 4: Pos 12-13, Length 2: Observation Hour Hour of observation,

rounded to nearest whole hourField 5: Pos 14-19, Length 6: Air Temperature The temperature of the

air UNITS: Degrees Celsius SCALING FACTOR: 10 MISSING VALUE: -9999Field

6: Pos 20-24, Length 6: Dew Point Temperature The temperature to

which a given parcel of air must be cooled at constant pressure and

water vapor content in order for saturation to occur. UNITS: Degrees

Celsius SCALING FACTOR: 10 MISSING VALUE: -9999

假設我們有這樣一個需求:每當我們上傳一個觀測點的資料gz檔案,我們需要統計出該觀測點的最高溫度,并且在輸出中要同時記錄該觀測點的站點代碼(從檔案名擷取)。

首先我們在騰訊雲COS對象存儲上建立兩個bucket,fredtest bucket用來上傳源資料檔案,output bucket用來生成輸出檔案。

使用騰訊雲無伺服器雲函數(SCF)分析天氣資料

存儲桶清單

如果需要模拟批量上傳,可以參考下面的Python腳本,其本質就是通過FTP拉取資料然後上傳到COS。

https://github.com/xianl/SCF/blob/master/download.py

下面來編寫具體的實作函數,主要需要完成下面幾件事情。

  • 1.上傳檔案後函數觸發,擷取上傳檔案的路徑
  • 2.調用COS SDK下載下傳該檔案,儲存到/tmp目錄
  • 3.解壓檔案,讀出資料内容
  • 4.處理資料,計算出溫度最大值
  • 5.将監控點代号以及計算出來的溫度最大值除以10儲存到/tmp目錄
  • 6.将最終結果上傳到COS output bucket。

核心部分的代碼實作如下,完整代碼可參考https://github.com/xianl/SCF/blob/master/action.py。

需要了解的是,main_handler的event參數将傳入所上傳檔案的資訊,其本質是一個json檔案,例如event'Records''cos''name'可以拿到bucket資訊。

def action_handler(event, context):

    #Create CosClient to upload/download COS file
    appid = 1253142785      # change to user's appid
    secret_id = u'xxx'   # change to user's secret_id
    secret_key = u'xxx'  # change to user's secret_key
    region = u'sh'          # change to user's region
    cos_client = CosClient(appid, secret_id, secret_key, region)

    #specify the source and destination bucket location
    source_bucket = event['Records'][0]['cos']['cosBucket']['name']
    source_bucket_file_key = '/' + event['Records'][0]['cos']['cosObject']['key'].split('/')[-1]
    source_file_name = source_bucket_file_key.split('/')[-1].split('.')[0]
    dest_bucket = u'output'
    dest_bucket_file_key = u'/max_temperature_'+ source_file_name

    #specify the temp file location
    source_file_tmp_path = u'/tmp/' + source_file_name
    dest_file_temp_path = u'/tmp/max_temperature_' + source_file_name

    #download the source file from cos bucket and take actions
    download_ret = download_file(cos_client,source_bucket,source_bucket_file_key,source_file_tmp_path)
    if download_ret == 0:
        dest_file_temp = open(dest_file_temp_path, 'w')
        max_temp = -999.9

        #find the maximum temperature
        with gzip.open(source_file_tmp_path) as inputfile:
            for line in inputfile:
                temp = int(line[14:19]) / 10.0
                if temp > max_temp:
                    max_temp = temp

        #write the result to the temp file and upload to the cos bucket
        dest_file_temp.write(source_file_name + ' ' + str(max_temp))
        dest_file_temp.close()
        upload_ret = upload_file(cos_client, dest_bucket, dest_bucket_file_key, dest_file_temp_path)
        return upload_ret
    else:
        return -1      

在COS的同一個區域建立SCF雲函數,執行方法為SCF的函數入口,設定為index.main_handler, 同時在代碼框内貼入代碼。

使用騰訊雲無伺服器雲函數(SCF)分析天氣資料

無伺服器函數代碼

第三步需要選擇觸發方式為COS觸發,并選擇COS bucket為fredtest。

使用騰訊雲無伺服器雲函數(SCF)分析天氣資料

設定觸發方式

在fredtest bucket上傳010010-99999-2017.gz檔案之後,檢視SCF的日志可以看到函數被正常觸發了。

使用騰訊雲無伺服器雲函數(SCF)分析天氣資料

無伺服器函數日志

output bucket同時會按照代碼邏輯生成max_temperature_010010-99999-2017 檔案

使用騰訊雲無伺服器雲函數(SCF)分析天氣資料

輸出檔案

檔案内容為站點代碼以及最後計算出的最大溫度14.3℃,滿足預期需求。至此,一個簡單的SCF實際資料應用場景的demo就跑完了。

使用騰訊雲無伺服器雲函數(SCF)分析天氣資料

計算結果

總結

可以看到騰訊雲SCF非常适用這種單入單出的資料處理場景,業務人員隻需編寫代碼并在界面上進行簡單的配置即可實作業務邏輯,而其所需接觸的對象僅僅是例如對象存儲,Message Queue,資料庫等應用層對象而完全不需關心伺服器,網絡等基礎資源,簡化了很大一部分人為操作。如果能夠再結合API Gateway等産品,也能夠做到各個系統的業務解耦以及疊代開發。

另外,至于前文提到的批量計算,目前騰訊雲還處于内測階段,等公測之後我還會寫一篇文章利用2017年的上萬各監測點的資料使用批量計算來計算出2017年整年的最高溫度,盡請期待。

相關閱讀

騰訊雲無伺服器雲函數架構精解

使用騰訊雲 scf 雲函數壓縮 cos 對象存儲檔案

serverless 初探

此文已由作者授權雲+社群釋出,轉載請注明原文出處

海量技術實踐經驗,盡在雲加社群!

https://cloud.tencent.com/developer

繼續閱讀