顯示具有 Internet of Vehicles 標籤的文章。 顯示所有文章
顯示具有 Internet of Vehicles 標籤的文章。 顯示所有文章

2016年2月22日 星期一

透過雲端服務與Node.js打造車聯網大數據分析平台

車聯網(Internet of Vehicles)已經是今年在汽車界熱門的議題,從McKinsey去年的物聯網報告來看,車聯網可以做的事情共有六種,包含「改善汽車的安全與可靠度」、「維修服務推薦」、「加強汽車連結」、「加強客戶體驗」、「提供保險動態價格」、「增加車隊效率與降低成本」,但是做這些事情之前基礎設施就變得非常重要,如果沒有一個好的雲端平台去收集資料、儲存資料、分析資料,就無法與前面提到的服務做整合。

因此本次教學筆者嘗試使用了一個雲端平台(IBM Bluemix)去進行車聯網的系統實作,希望透過一個簡單的實作,讓有興趣的朋友能掌握技術要領,並實際體驗車聯網的初步成果,如下圖所示。



首先我們必須要有Bluemix帳號,進入了平台以後找到,在型錄裡面,找到「Internet of Things Platform」,如下圖所示:


接著點選他,然後在Service Name上面打入我們的服務名稱,像筆者就打「iotcc」,然後點選「Create」將服務進行啟動,如下圖:


之後您回到自己的儀錶板,就可以看到如下的畫面:


接著點選服務名稱,以筆者為例是「iotcc」,點進去以後,再點選「Launch Dashboard」,如下圖:


接著點選IBM Watson IoT Platform的「Devices」選項。


選擇「Add Device」進行新增裝置。


首先我們必須先建立汽車裝置的裝置類型,因此點選「Create Device Type」進行裝置類型新增。

點選「Create device type」的選項。
輸入裝置的一般資訊,包含名稱、描述,筆者這邊分別填「Vehicle」與「Internet of things」,然後點選Next。
以下的幾個步驟,都是針對裝置的細部描述做紀錄,建議都先以「Next」做跳過的動作,


創建完基本的裝置樣本之後,直接在下個畫面中選擇建好的「Vehicle」裝置樣本,並點選「Next」進行裝置的建立。
接著我們新增第一個車聯網裝置「vehicle1」
接著一直下一步到取得裝置的連接號碼:



注意:到這裡的時候,就要記錄下vehicle1的存取ID與相關資料。
筆者在這個時候就會把上面紅框的資料做紀錄,等下要放到車聯網平台上。
接著以此類推,做兩次,將「vehicle2」、「vehicle3」完成另外兩個裝置的設定。

接著我們到「ACCESS」去獲取組織的ID,如下圖所示:
選擇「api keys」然後點選「Generate API Key」,如下圖所示:
接著紀錄一下下圖中的API Key,等下我們會放到程式當中。
到這一步,終於完成IBM Bluemix上的裝置設定,接下來我們要寫一個範例去進行佈署的動作,筆者修改了一個國外的範例給大家下載,如果無法下載可到筆者GitHub下載,裡面包含了兩份檔案:
  1. 檔案「iotcc」為預計佈署到雲端上的車聯網軟體,主要用Node.js、HTML、CSS所撰寫
  2. 檔案「cf-cli-installer_6.15.0_winx64」進行Git Push的工具
首先解壓縮後打開「manifest.yml」檔案,修改您的服務名稱,以下圖為例:
請輸入
hostconnectedcar
nameconnectedcar
instances3 (指3台裝置)
接著到public\config資料夾裡面,打開「settings.js」檔案,將前面申請的裝置與組織ID都輸入到該檔案當中,如下:
iot_deviceType
輸入我們在前面建立的「Vehicle」。
iot_deviceOrg
輸入在前面裝置申請時獲得的「Organization ID」,如:k8buaf。
iot_deviceSet中的deviceId與token:
輸入前面裝置申請獲得的Device IDtoken的部分則輸入Authentication Token如:A!ggkk99y_sstbt)vY

最後是填入組織的ID
iot_apiKey輸入前面申請到的API Key
iot_apiToken輸入前面申請的Authentication Toke

大致上設定完成,最後我們要Cloud Foundry的工具,將車連網服務佈署到雲端平台上,因此要安裝「cf_installer」,基本上一直下一步就可完成安裝。

接著我們打開CMD,進行登入的動作,如下圖所示,筆者先切換到iotcc資料夾底下,打入「cf login」的動作,使用一開始註冊的帳號密碼登入即可。

登入成功後會顯示下面畫面。

最後打入「cf push」進行Deploy的動作

看到下圖畫面表示已經佈署成功。

最後輸入http://<您設定的host名稱>.mybluemix.net,即可看到服務,也可參考筆者下圖成果。


接著可以透過「互動」的功能達到跟模擬汽車互動的動作。

時間的關係,這次就先暫時介紹到這邊吧!



2015年12月19日 星期六

車聯網的即時服務架構-以Uber為例

大數據的架構是很有趣的,因為牽涉既有傳統的資訊設施,也需融合新擁有的數據儲存與分析設施,而且在不同的使用情境下,架構也不相同。

因此想切入大數據的公司,常常面臨到的問題除了「不知要如何開始」之外,就是「要如何建構可以容易擴展的平台」,以及在最節省資源的情況下,如何給予使用者最佳的服務。而筆者所協助的公司,也常常面臨到技術太多無從選擇,導致不知道如何將新技術配置到架構上。因此大部分的大數據專案常常因為「想做的題目太多,不知如何做起」、「技術太多種,不知從何用起」導致上層也無法承擔與拿定主意,最後不是中途喊卡,就是專案失敗。


近幾年車聯網(Internet of Vehicles)的議題開始被討論,而筆者也正在觀察這種不同聯網的技術架構,因此就以最近由優步(Uber)的首席系統架構師Matt Ranney發表的文章中,它們透過開放原始碼建構的即時服務平台Disco,從中整理一些車聯網建構即時服務系統的方式。

首先我們可以從Uber的現有狀態來觀察,甚麼樣的需求,會需要建置這樣的服務平台? 從Uber的全球服務來看,他們每秒必須面臨一百萬筆Uber車子的Geospatial的索引,以及數千個節點的連接。

Uber整理了幾個他們從2009年開始至今約6年間採用的技術包含「Node.jsPythonJavaGoNative applications on iOS and AndroidRedisPostgresMySQLRiakTwitter's Twemproxy for RedisGoogle's S2 Geometry LibraryringpopTChannelThrift筆者針對這些技術整理技術概要介紹如下

  1. Node.js
    Node.js從2009年誕生之今,也是約6年期間。主要流行的原因是將Java Script帶到後端(Back end)應用,以前專門用JS寫前端的人,只要學Node.js就可以開始寫後端(Back end),所以這些人就變成所謂的全端(Full Stack)。

    Node.js的底層是採用Google V8的引擎,以C++撰寫而成,特性在於撰寫即時的網站服務(Real-Time Web Service),Node.js有所謂的異步I/O模型,一般服務器處理的方式採用同步I/O的方式,如:我們丟一個檔案,服務器就把他印出來,是一個直觀的做法。但在互聯網的環境,大量的請求就會把CPU資源吃光。而異步I/O的方式就是遇到I/O請求就先往後台丟,讓CPU能先處理任務,這樣單一CPU就可以處理多個問題,所以Node.js的異步I/O模型又稱非阻塞I/O。Uber採用Node.js來處理API、訂單的各種即時服務。
  2. Python
    正如其名蟒蛇(Python)一樣,有龐大又好用的套件支持,對於一些想要快速進行服務雛形,都可以透過Python很快的去實作。Python從1991年誕生之今,以優雅、明確、簡單的概念讓開發者可以很快的把各種服務想法快速的實現,因此Uber就是利用Python這種方便「整合」的特性,各種服務機制透過Python來撰寫。
  3. Java
    這個語言資訊相關科系的同學是再熟悉不過了,Java從1995年誕生後至今都仍然很活躍的語言,近年最知名的應用就是Android作業系統,因為Java的語法嚴謹、普遍,因此有些開源軟體會採用Java作為主要開發語言,則虛擬機採用C/C++來做撰寫。Uber則是透過Java與前面的Python整合一些地理資訊上的應用。
  4. Go
    這個語言與Node.js都是在2009年出現,這個語言非常有野心,據說要取代C/C++,當然筆者認為短時間不太可能出現這樣的情形。不過Go因為有了Google的支持,使得在語言發展上較其他語言有更大的優勢。不過筆者觀察的特色在於Go處理需要擴展性(Scalability)與平行性(Concurrency),有很大的優勢,因此Uber把原本要給C/C++要做的事情,部分交給了Go來做處理,藉此提高系統的運作效率。
  5. Native applications on iOS and Android
    因為Uber的服務講究的是好的性能與效率,因此開發了原生的iOS與Android APP。誠如前面提到的Android是採用Java撰寫,而iOS早期為Objective-C所編輯,從2014年開始改Swift語言做開發。
  6. Redis
    這個資料庫也是在2009年出現,屬於NoSQL的一種,採用鍵值(Key–value)的方式儲存資料,它最大的特性在於資料都是儲存於記憶體上,便於使用與高吞吐的情境上,屬於CAP理論中的CP,也就是一致性(Consistent)與分隔容忍性(Partition Tolerance)。Uber採用它做暫存的動作,讓服務能處在低延遲高效率的狀態上。Uber有不少的應用都是採用基於Twemproxy的Redis,使服務能保持不間斷。
  7. PostgreSQLMySQL
    PostgreSQL與MySQL一樣都是傳統關聯式資料庫(RDBMS),跟Java一樣兩個都是1995年誕生,目前MySQL一直在市場上有一定程度的擁護者,不過近幾年因為MySQL商業化後,當初開發MySQL的開發者轉至MariaDB,因此稍微式微一些。反觀PostgreSQL的使用者仍保持開源的方式持續成長,筆者認為它與MySQL最大的不同在於對於地理資訊的處理有強大的功能支持,因此除了日常服務,PostgreSQL更能處理有關地理資訊的資料儲存。不過Uber看起來是把PostgreSQL作為服務一開始的資料庫,筆者認為應該就是看到PostgreSQL的特性,而MySQL則是來當作一般日常服務的資料儲存。
  8. Riak
    幾年前看到Riak的時候,是因為正在了解Hadoop的架構,Riak較Hadoop更為年輕,是在 2009年誕生。Riak是採用鍵值(Key–value)的方式儲存資料,在CAP理論中屬於AP,也就是可用性(Availability)與分隔容忍性(Partition Tolerance),也就特性是以確保寫入與讀出為主。不過Riak跟Cassandra一樣沒有Master/Slave,因此資料在吞吐上主機的壓力較小。Uber將Riak應用在調度系統上,看起來相當合理,因為即時的調度在資料輸入與輸出上需要不斷的吞吐。
  9. Twitter's Twemproxy for Redis
    Twemproxy是Twitter所推出的開放原始碼,是Twitter貢獻前面提到的Redis的架構,以提供更高效能的服務。Twitter採用龐大的Redis集群提供時間軸的訊息顯示,而Twemproxy最大的特色在於當一個Node失效的時候,自動卸載與自動重新連接,因此Uber採用它來做低延遲的服務應用。
  10. Google's S2 Geometry Library
    過去的Uber只能看到Uber的供應量,但其實無法完全掌握汽車與客戶間的距離作最佳化的處理,因此為了強化匹配的效率,Uber要將每個區塊變成一個id,Uber透過S2切成一個個細胞(cell),讓所有的乘客可以因此降低等待時間,因此透過S2的覆蓋函數,Uber不再只是尋找可以載乘客的司機,更能找到可以「順路」載乘客的司機。
  11. Ringpop
    Ringpop是Uber自己開發的模組,是給Node.js使用。它是一個採用Gossip協定,降低服務的出錯機率,在Gossip協定中一旦節點都獲得認證, 它們就可以快速地進行查詢與散播訊息,Gossip以前最常出現在P2P的服務當中。Uber就是把Gossip結合可擴充可傳導的弱一致性行程群組成員協定(SWIM)放到Node.js當中。
  12. TChannel
    TChannel透過Ringpop的實現,Uber就建立了屬於自己遠端調用程式(PRC)機制,它們稱為TChannel,使得每一個請求與回應都能獨立與安全的運作,因此TChannel在搭配Redis下,通訊效率比HTTP快,Uber正在改變早期採用HTTP與Json通信模式,往TChannel的Thrift通訊方式作發展。
  13. Thrift
    Thrift最早在2007年前,是被Facebook開發,且被用來處理系統間的RPC服務,最大的特色在於支援相當多的語言,快速實現RPC的服務。

Uber服務平台處理的工作,就是協助每一位駕駛與消費者的能夠緊密連接,這件事情的挑戰在於如何在即時的狀態下去做資訊動態的連接,像是一位消費者正準備要找車搭,在自己的手機APP上,系統會顯示附近的車輛,這些過程都是即時呈現,所以服務平台必須能夠快速捕捉駕駛的位置,並回傳到手機APP上,提供準備找車的消費者查詢。

這在日常的時段,做匹配(Matching)的工作還可以應付,當在過新年的時候,才是Uber面臨的巨大挑戰,因為跨年後想要搭車的消費者是瞬間暴增,就像是以前SMS時代,大家跨年之後,想傳簡訊給身邊的朋友祝福,卻發現簡訊發不出去,發生系統滿載的問題,Uber服務平台的挑戰亦同。

大家都知道Uber的服務平台,主要以iOS與Android為主,而真正在調度的機制,幾乎是採用Node.js完成,因為Node.js擁有Java script的特性,資料吞吐上能保有較佳的彈性,因此除了iOS與Android之外,資料介接則是採用Node.js語言建構。以下是其他包含的機制技術:

地圖(Maps/ETA): 最短抵達時間(Estimated Time of Arrival簡稱ETA)該機制被使用來估計抵達的時間,除了可以顯示街道地圖,也可以呈現估計時間,採用了Python、C++與Java語言,採用Python是為了要整合機制,採用C++與Java則考慮提升執行效率。

服務(Service):該服務主要用於提供商業物流服務,大部分是採用Python進行撰寫,因為Python具備開發彈性,並同時採用Microservice的方法。

資料庫(Database):早期採用PostgresSQL,後來採用Redis主要是與Twemproxy結合。也有採用MySQL於線上服務網站。另外還有一些調度服務是採用Riak進行儲存。

配套服務:配套的系統服務,包含收集排名、信件通知、更新資料庫、付款時程......等,都是採用Python進行撰寫,當然還是考量Python的語言可讀性高,且具備開發彈性。

金流:Uber的金流介接都與目前的金流公司合作。


面對Uber接下來的急速增長的客戶數量挑戰,Uber提出新系統的建構想法,像是他們增加了更詳細的資訊交換內容,包含供給端與消費端,供給端提供座位數、車型、小孩座位,消費端則提供需求座位數,結合地理資訊(Geo),做這兩端的調度最佳化(Dispatch Optimization)。

筆者整理Uber的幾個服務項目的新建構思維,如下:
  1. 供給與需求雙方的資訊媒合,消費端的需求可以被快速媒合。
  2. 當消費端出現,服務平台能夠能快速找出最靠近的候選車輛。
  3. 透過較新的技術達到服務的可用性,確保服務不斷線
  4. 每一個服務都有具備重複詢問的功能,確保每一個訂單都能運作。
  5. 從一個可以提供載客的服務,走到可以提供順路載客的服務。
  6. 利用新技術達到減少空載、減少等待、整體到達時間(ETA)最短的服務


基本上現在許多資訊服務都是各種技術混用,因此筆者常需要涉獵各種不同的大數據運行架構,本篇主要針對Uber的技術做了一些整理,希望能提供給需要了解各種技術架構整合的讀者有初步的了解,如果讀者有興趣,也歡迎自行到下面參考資料中作進一步的閱讀。


其他資料參考: