這篇文章主要介紹“基于TableStore的物聯(lián)網(wǎng)元數(shù)據(jù)管理怎么實現(xiàn)”,在日常操作中,相信很多人在基于TableStore的物聯(lián)網(wǎng)元數(shù)據(jù)管理怎么實現(xiàn)問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”基于TableStore的物聯(lián)網(wǎng)元數(shù)據(jù)管理怎么實現(xiàn)”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
創(chuàng)新互聯(lián)主要企業(yè)基礎(chǔ)官網(wǎng)建設(shè),電商平臺建設(shè),移動手機平臺,重慶小程序開發(fā)等一系列專為中小企業(yè)按需搭建網(wǎng)站產(chǎn)品體系;應(yīng)對中小企業(yè)在互聯(lián)網(wǎng)運營的各種問題,為中小企業(yè)在互聯(lián)網(wǎng)的運營中保駕護航。常見的企業(yè)級無線接入方案有兩種,分別被稱作廋AP和胖AP。瘦AP(AC+AP)架構(gòu)為比較傳統(tǒng)的企業(yè)級無線接入方案,主要優(yōu)點就是漫游體驗好,但是AC宕機的話會導(dǎo)致所屬的AP全部無法工作。對于大型的辦公場所,漫游的需求相對較弱,新型的胖AP(無AC,不會因為AC宕機導(dǎo)致網(wǎng)絡(luò)不可用)+ 云端控制器架構(gòu)成為了新興的一種企業(yè)無線接入方案,運維人員通過云端對AP進行監(jiān)控與管理。
某公司擁有無線AP約10,000臺、接入終端(STA)100,000個。設(shè)備以一定的周期上報其狀態(tài)到云端,云端將監(jiān)控數(shù)據(jù)持久化后供用戶查看。
每個AP設(shè)備會以10s的周期上報其當前狀態(tài),上報數(shù)據(jù)格式為json,其格式如下:
AP狀態(tài):
{ "ap_mac": "11:22:33:86:D9:E8", // AP WAN口MAC地址,AP設(shè)備唯一標識 "report_time": 1532315501985, // 上報時間戳,毫秒 "on_time": 1531417181972, // 設(shè)備上線時間戳,毫秒 "sta_cnt": 2, // 終端數(shù)量 "cpu_usage": 12, // CPU使用率 "memory_usage": 38, // CPU使用率 "wan_recv_speed": 280, // WAN口下行速率 單位bps "wan_sent_speed": 45348, // WAN口上行速率 單位bps }
通過MAC地址查看每個AP最新的狀態(tài)。
用戶需要在管理系統(tǒng)上對基于各種條件對設(shè)備進行查詢。
需要對AP的各種指標進行排序,以便找出故障設(shè)備。
我們將上述的需求分為兩種:
多維查詢。
排序。
基于這兩大類需求,我們給出如下的架構(gòu)選型比較。
針對這種IOT場景的設(shè)備狀態(tài)監(jiān)控數(shù)據(jù),下面針對幾種常見方案做比較。
將設(shè)備上報的狀態(tài)數(shù)據(jù)直接寫入MySQL,并使用MySQL自帶的查詢、排序語句對數(shù)據(jù)進行分析,這種架構(gòu)最為簡單,用戶運維成本較低。
這種架構(gòu)僅僅適用于小規(guī)模量的數(shù)據(jù),在大規(guī)模數(shù)據(jù)的情況下,MySQL的內(nèi)部架構(gòu)也導(dǎo)致了無法創(chuàng)建出一種萬用的索引來滿足多維查詢的需求。并且MySQL底層使用的是B+數(shù)作為存儲結(jié)構(gòu),會有隨機寫的問題,寫入性能較差。
MySQL在使用前必須指定表結(jié)構(gòu),也就是說后續(xù)新增需求的話,必須要修改表結(jié)構(gòu),在數(shù)據(jù)量較大的情況下修改表結(jié)構(gòu)很容易造成鎖表導(dǎo)致線上故障。
由于MySQL的檢索能力較弱,MySQL + Elasticsearch也是業(yè)界比較常見的方案。用戶將數(shù)據(jù)寫入MySQL,并使用binlog訂閱工具(如 canal )將數(shù)據(jù)異步寫入Elasticsearch,架構(gòu)如下圖所示:
其中Canal Client需要用戶自己編寫與部署。相比單MySQL的架構(gòu),該方案很好地解決了MySQL在多維查詢和指定列排序能力弱的問題。但是帶了的問題也比較多:
Canal與Elasticsearch需要用戶自己部署,帶來的運維成本也相對提升。
Canal Client側(cè)負責(zé)讀取Canal傳輸過來MySQL增量改變數(shù)據(jù),數(shù)據(jù)的一致性是需要用戶自己保證的。
表格存儲底層存儲使用的LSM模型,很好地解決了MySQL寫入性能差的問題,特別適合IOT這種寫多讀少的場景。
用戶將數(shù)據(jù)寫入表格存儲后系統(tǒng)內(nèi)部會將數(shù)據(jù)異步同步到SearchIndex,數(shù)據(jù)寫入TableStore到數(shù)據(jù)可查約有毫秒到秒級別的延遲,用戶無需關(guān)注運維相關(guān)的問題,數(shù)據(jù)一致性也有系統(tǒng)內(nèi)部保證,做到了開箱即用。
基于上面的比較,表格存儲更適合存儲AP的狀態(tài)數(shù)據(jù),并且通過SearchIndex可以很容易地完成多維查詢以及排序。簡明的系統(tǒng)整體架構(gòu)如下圖所示:
表格存儲底層使用主鍵的第一列將數(shù)據(jù)均分到對應(yīng)的分區(qū)上,以達到負載均衡的目的。我們知道MAC地址的前3個字節(jié)為廠商碼,也就是說如果同一個廠家生產(chǎn)出來的設(shè)備MAC地址前3個字節(jié)大多會是相同的,如果直接使用MAC地址做主鍵的話可能會導(dǎo)致數(shù)據(jù)熱點,所以我們推薦對MAC地址做MD5之后做第一列主鍵。關(guān)于表結(jié)構(gòu)設(shè)計的最佳實踐詳見這里 。
表名:wifi_ap_status
列類型 | 列名 | 類型 | 示例 | 備注 |
---|---|---|---|---|
主鍵列 | pk0 | String | 1b5de627b4a25553baf1f72af9afb96d | MD5(ap_mac),對ap_mac做MD5 |
值列 | ap_mac | String | 11:22:33:44:55:66 | AP MAC地址 |
report_time | Integer | 1537363646533 | UTC時間戳,毫秒 | |
on_time | Integer | 1537363646533 | 同上 | |
sta_cnt | Integer | 10 | 所連接終端數(shù) | |
cpu_usage | Integer | 20 | CPU使用率 | |
memory_usage | Integer | 50 | 內(nèi)存使用率 | |
wan_recv_speed | Integer | 817 | 收數(shù)據(jù)速率,單位bps | |
wan_sent_speed | Integer | 2411 | 發(fā)數(shù)據(jù)速率,單位bps |
下面將以 AP狀態(tài) 作為例子,給出全流程的代碼示例。
SyncClient syncClient = new SyncClient( "$endpoint", "$accessKeyId", "$accessKeySecret", "$instanceName" );
SyncClient對象為線程安全,如果使用Spring的話可以將其作為一個單例Bean注入到其他對象中使用
表的創(chuàng)建可以在控制臺上完成,也可以通過SDK完成,如果使用SDK的話代碼示例如下
// 指定表名TableMeta tableMeta = new TableMeta("wifi_ap_status");// 指定主鍵列,根據(jù)上面的表結(jié)構(gòu)設(shè)計,這邊只有pk0一個主鍵列tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema("pk0", PrimaryKeyType.STRING)); CreateTableRequest createTableRequest = new CreateTableRequest(tableMeta, new TableOptions(-1, 1)); syncClient.createTable(createTableRequest);
與創(chuàng)建表相同,SearchIndex的創(chuàng)建可以通過控制臺完成,如果使用SDK的話,示例如下:
CreateSearchIndexRequest createSearchIndexRequest = new CreateSearchIndexRequest(); createSearchIndexRequest.setIndexName("wifi_ap_status"); createSearchIndexRequest.setTableName("wifi_ap_status"); IndexSchema indexSchema = new IndexSchema(); indexSchema.setIndexSetting(new IndexSetting(5)); indexSchema.setFieldSchemas(Arrays.asList( new FieldSchema("ap_mac", FieldType.TEXT).setIndex(true), // 可搜索 new FieldSchema("report_time", FieldType.LONG).setIndex(true).setEnableSortAndAgg(true), // 可搜索并可排序 new FieldSchema("sta_cnt", FieldType.LONG).setIndex(true).setEnableSortAndAgg(true), new FieldSchema("cpu_usage", FieldType.LONG).setIndex(true).setEnableSortAndAgg(true), new FieldSchema("memory_usage", FieldType.LONG).setIndex(true).setEnableSortAndAgg(true) )); createSearchIndexRequest.setIndexSchema(indexSchema); CreateSearchIndexResponse resp = syncClient.createSearchIndex(createSearchIndexRequest);
用戶只需使用原表格存儲的寫入功能將數(shù)據(jù)寫入即可,表格存儲內(nèi)部會自動將數(shù)據(jù)導(dǎo)入SearchIndex,無需關(guān)心內(nèi)部實現(xiàn)。
PutRowRequest putRowRequest = new PutRowRequest(); RowPutChange rowPutChange = new RowPutChange("wifi_ap_status"); String apMac = "11:22:33:86:D9:E8";// 通過AP MAC計算MD5,防止產(chǎn)生數(shù)據(jù)熱點,這邊使用了apache的commons-codec庫String pk0 = DigestUtils.md5Hex(apMac); PrimaryKey pk = new PrimaryKey(new PrimaryKeyColumn[]{ new PrimaryKeyColumn("pk0", PrimaryKeyValue.fromString(pk0)) }); rowPutChange.setPrimaryKey(pk); rowPutChange.addColumns(new Column[]{ new Column("ap_mac", ColumnValue.fromString(apMac)), new Column("report_time", ColumnValue.fromLong(System.currentTimeMillis())), new Column("on_time", ColumnValue.fromLong(System.currentTimeMillis())), new Column("cpu_usage", ColumnValue.fromLong(56)), new Column("sta_cnt", ColumnValue.fromLong(4)), new Column("memory_usage", ColumnValue.fromLong(43)), new Column("wan_recv_speed", ColumnValue.fromLong(280)), new Column("wan_sent_speed", ColumnValue.fromLong(45348)), }); putRowRequest.setRowChange(rowPutChange); syncClient.putRow(putRowRequest);
數(shù)據(jù)讀取分為兩種:
1.基于原生的表格存儲的主鍵獲取
2.基于SearchIndex功能獲取
下面對于這兩種不通模式的讀取分別舉例說明
通過主鍵獲取AP狀態(tài)的話是直接從表格存儲的表中直接獲取的。也就是說,在通過主鍵獲取數(shù)據(jù)的時候是不需要通過SearchIndex功能的,代碼示例如下:
GetRowRequest getRowRequest = new GetRowRequest(); String apMac = "11:22:33:86:D9:E8";// 通過AP MAC計算MD5,防止產(chǎn)生數(shù)據(jù)熱點,這邊使用了apache的commons-codec庫String pk0 = DigestUtils.md5Hex(apMac);// 設(shè)置主鍵PrimaryKey pk = new PrimaryKey(new PrimaryKeyColumn[]{ new PrimaryKeyColumn("pk0", PrimaryKeyValue.fromString(pk0)) }); SingleRowQueryCriteria singleRowQueryCriteria = new SingleRowQueryCriteria("wifi_ap_status", pk); singleRowQueryCriteria.setMaxVersions(1); getRowRequest.setRowQueryCriteria(singleRowQueryCriteria); GetRowResponse rowResponse = syncClient.getRow(getRowRequest); Row row = rowResponse.getRow();// 獲取主鍵列PrimaryKey primaryKey = row.getPrimaryKey();for (PrimaryKeyColumn primaryKeyColumn : primaryKey.getPrimaryKeyColumns()) { System.out.println("PrimaryKeyColumn:(" + primaryKeyColumn.getName() + ":" + primaryKeyColumn.getValue() + ")"); }// 獲取值列for (Column column : row.getColumns()) { System.out.println("Column:(" + column.getName() + ":" + column.getValue() + ")"); }
為了方便描述,下面通過SQL(僅為表示具體需求,SearchIndex暫不支持SQL語句)+代碼的形式給出示例來描述我們的場景。
如果需要通過非主鍵列進行多維查詢,我們可以使用syncClient的search方法,在上面的
例子
中,我們?yōu)閣ifi_ap_status表創(chuàng)建了SearchIndex,并且指定了索引列。
如果要實現(xiàn)下面的SQL:
SELECT*FROM wifi_ap_statusWHERE ap_mac LIKE '%86:D9:E8%' AND sta_cnt >= 2
用java語言實現(xiàn)的話,代碼如下
SearchQuery searchQuery = new SearchQuery();// 使用BoolQuery來實現(xiàn)組合條件查詢,本例搜索了ap_mac包含86:D9:E8并且sta_cnt大于等于2的數(shù)據(jù)BoolQuery query = new BoolQuery();// 使用短語搜索模糊匹配ap_macMatchPhraseQuery macQuery = new MatchPhraseQuery(); macQuery.setFieldName("ap_mac"); macQuery.setText("86:D9:E8");// 使用范圍查詢sta_cntRangeQuery staCntQuery = new RangeQuery(); staCntQuery.setFieldName("sta_cnt"); staCntQuery.setFrom(ColumnValue.fromLong(2), true); query.setMustQueries(Arrays.asList( macQuery, staCntQuery )); searchQuery.setQuery(query);// 構(gòu)建搜索請求SearchRequest searchRequest = new SearchRequest( "wifi_ap_status", // 表格存儲表名 "wifi_ap_status", // SearchIndex索引名 searchQuery );// 設(shè)置需要返回的表列SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet();// 設(shè)置返回所有列columnsToGet.setReturnAll(true); searchRequest.setColumnsToGet(columnsToGet);// 搜索請求SearchResponse searchResponse = syncClient.search(searchRequest); Listrows = searchResponse.getRows();for (Row row : rows) { PrimaryKey primaryKey = row.getPrimaryKey(); for (PrimaryKeyColumn primaryKeyColumn : primaryKey.getPrimaryKeyColumns()) { System.out.println("PrimaryKeyColumn:(" + primaryKeyColumn.getName() + ":" + primaryKeyColumn.getValue() + ")"); } for (Column column : row.getColumns()) { System.out.println("Column:(" + column.getName() + ":" + column.getValue() + ")"); } }
排序功能也是我們的常見需求,比如我們需要查看在某個條件下掛載終端數(shù)最多的幾個AP,如果用SQL語句描述的話如下:
SELECT*FROM wifi_ap_statusWHERE ap_mac LIKE '%11:22:33%'ORDER BY sta_cnt DESC
如果用代碼表示的話,如下:
SearchQuery searchQuery = new SearchQuery();// 使用短語搜索模糊匹配ap_macMatchPhraseQuery macQuery = new MatchPhraseQuery(); macQuery.setFieldName("ap_mac"); macQuery.setText("11:22:33"); searchQuery.setQuery(macQuery);// 排序選項,sta_cnt降序FieldSort staCntSorter = new FieldSort("sta_cnt"); staCntSorter.setOrder(SortOrder.DESC); searchQuery.setSort(new Sort(Collections.singletonList( staCntSorter )));// 構(gòu)建搜索請求SearchRequest searchRequest = new SearchRequest( "wifi_ap_status", "wifi_ap_status", searchQuery );// 設(shè)置需要返回的表列SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet();// 設(shè)置返回所有列columnsToGet.setReturnAll(true); searchRequest.setColumnsToGet(columnsToGet);// 搜索請求SearchResponse searchResponse = syncClient.search(searchRequest); Listrows = searchResponse.getRows();
到此,關(guān)于“基于TableStore的物聯(lián)網(wǎng)元數(shù)據(jù)管理怎么實現(xiàn)”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
當前文章:基于TableStore的物聯(lián)網(wǎng)元數(shù)據(jù)管理怎么實現(xiàn)-創(chuàng)新互聯(lián)
標題路徑:http://weahome.cn/article/dghdeh.html