真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

基于TableStore的物聯(lián)網(wǎng)元數(shù)據(jù)管理怎么實(shí)現(xiàn)

這篇文章主要介紹“基于TableStore的物聯(lián)網(wǎng)元數(shù)據(jù)管理怎么實(shí)現(xiàn)”,在日常操作中,相信很多人在基于TableStore的物聯(lián)網(wǎng)元數(shù)據(jù)管理怎么實(shí)現(xiàn)問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”基于TableStore的物聯(lián)網(wǎng)元數(shù)據(jù)管理怎么實(shí)現(xiàn)”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、小程序定制開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了寧海免費(fèi)建站歡迎大家使用!

背景

常見的企業(yè)級(jí)無(wú)線接入方案有兩種,分別被稱作廋AP和胖AP。瘦AP(AC+AP)架構(gòu)為比較傳統(tǒng)的企業(yè)級(jí)無(wú)線接入方案,主要優(yōu)點(diǎn)就是漫游體驗(yàn)好,但是AC宕機(jī)的話會(huì)導(dǎo)致所屬的AP全部無(wú)法工作。對(duì)于大型的辦公場(chǎng)所,漫游的需求相對(duì)較弱,新型的胖AP(無(wú)AC,不會(huì)因?yàn)锳C宕機(jī)導(dǎo)致網(wǎng)絡(luò)不可用)+ 云端控制器架構(gòu)成為了新興的一種企業(yè)無(wú)線接入方案,運(yùn)維人員通過云端對(duì)AP進(jìn)行監(jiān)控與管理。

某公司擁有無(wú)線AP約10,000臺(tái)、接入終端(STA)100,000個(gè)。設(shè)備以一定的周期上報(bào)其狀態(tài)到云端,云端將監(jiān)控?cái)?shù)據(jù)持久化后供用戶查看。

業(yè)務(wù)描述

每個(gè)AP設(shè)備會(huì)以10s的周期上報(bào)其當(dāng)前狀態(tài),上報(bào)數(shù)據(jù)格式為json,其格式如下:
AP狀態(tài):

{    "ap_mac": "11:22:33:86:D9:E8",  // AP WAN口MAC地址,AP設(shè)備唯一標(biāo)識(shí)    "report_time": 1532315501985,   // 上報(bào)時(shí)間戳,毫秒    "on_time": 1531417181972,       // 設(shè)備上線時(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
}

需求以及架構(gòu)選型

需求

  1. 通過MAC地址查看每個(gè)AP最新的狀態(tài)。

  2. 用戶需要在管理系統(tǒng)上對(duì)基于各種條件對(duì)設(shè)備進(jìn)行查詢。

  3. 需要對(duì)AP的各種指標(biāo)進(jìn)行排序,以便找出故障設(shè)備。
    我們將上述的需求分為兩種:

  4. 多維查詢。

  5. 排序。
    基于這兩大類需求,我們給出如下的架構(gòu)選型比較。

架構(gòu)選型

針對(duì)這種IOT場(chǎng)景的設(shè)備狀態(tài)監(jiān)控?cái)?shù)據(jù),下面針對(duì)幾種常見方案做比較。

MySQL

將設(shè)備上報(bào)的狀態(tài)數(shù)據(jù)直接寫入MySQL,并使用MySQL自帶的查詢、排序語(yǔ)句對(duì)數(shù)據(jù)進(jìn)行分析,這種架構(gòu)最為簡(jiǎn)單,用戶運(yùn)維成本較低。

這種架構(gòu)僅僅適用于小規(guī)模量的數(shù)據(jù),在大規(guī)模數(shù)據(jù)的情況下,MySQL的內(nèi)部架構(gòu)也導(dǎo)致了無(wú)法創(chuàng)建出一種萬(wàn)用的索引來(lái)滿足多維查詢的需求。并且MySQL底層使用的是B+數(shù)作為存儲(chǔ)結(jié)構(gòu),會(huì)有隨機(jī)寫的問題,寫入性能較差。
MySQL在使用前必須指定表結(jié)構(gòu),也就是說(shuō)后續(xù)新增需求的話,必須要修改表結(jié)構(gòu),在數(shù)據(jù)量較大的情況下修改表結(jié)構(gòu)很容易造成鎖表導(dǎo)致線上故障。

MySQL + 自建Elasticsearch

由于MySQL的檢索能力較弱,MySQL + Elasticsearch也是業(yè)界比較常見的方案。用戶將數(shù)據(jù)寫入MySQL,并使用binlog訂閱工具(如 canal )將數(shù)據(jù)異步寫入Elasticsearch,架構(gòu)如下圖所示:

基于TableStore的物聯(lián)網(wǎng)元數(shù)據(jù)管理怎么實(shí)現(xiàn)cdn.nlark.com/lark/0/2018/png/10828/1537264270336-ffe9ccf8-2ffc-4ec7-88ed-e826e97e1add.png">

其中Canal Client需要用戶自己編寫與部署。相比單MySQL的架構(gòu),該方案很好地解決了MySQL在多維查詢和指定列排序能力弱的問題。但是帶了的問題也比較多:

  1. Canal與Elasticsearch需要用戶自己部署,帶來(lái)的運(yùn)維成本也相對(duì)提升。

  2. Canal Client側(cè)負(fù)責(zé)讀取Canal傳輸過來(lái)MySQL增量改變數(shù)據(jù),數(shù)據(jù)的一致性是需要用戶自己保證的。

使用表格存儲(chǔ)的SearchIndex功能

表格存儲(chǔ)底層存儲(chǔ)使用的LSM模型,很好地解決了MySQL寫入性能差的問題,特別適合IOT這種寫多讀少的場(chǎng)景。

用戶將數(shù)據(jù)寫入表格存儲(chǔ)后系統(tǒng)內(nèi)部會(huì)將數(shù)據(jù)異步同步到SearchIndex,數(shù)據(jù)寫入TableStore到數(shù)據(jù)可查約有毫秒到秒級(jí)別的延遲,用戶無(wú)需關(guān)注運(yùn)維相關(guān)的問題,數(shù)據(jù)一致性也有系統(tǒng)內(nèi)部保證,做到了開箱即用。

結(jié)論

基于上面的比較,表格存儲(chǔ)更適合存儲(chǔ)AP的狀態(tài)數(shù)據(jù),并且通過SearchIndex可以很容易地完成多維查詢以及排序。簡(jiǎn)明的系統(tǒng)整體架構(gòu)如下圖所示:

基于TableStore的物聯(lián)網(wǎng)元數(shù)據(jù)管理怎么實(shí)現(xiàn)

表結(jié)構(gòu)設(shè)計(jì)

表格存儲(chǔ)底層使用主鍵的第一列將數(shù)據(jù)均分到對(duì)應(yīng)的分區(qū)上,以達(dá)到負(fù)載均衡的目的。我們知道MAC地址的前3個(gè)字節(jié)為廠商碼,也就是說(shuō)如果同一個(gè)廠家生產(chǎn)出來(lái)的設(shè)備MAC地址前3個(gè)字節(jié)大多會(huì)是相同的,如果直接使用MAC地址做主鍵的話可能會(huì)導(dǎo)致數(shù)據(jù)熱點(diǎn),所以我們推薦對(duì)MAC地址做MD5之后做第一列主鍵。關(guān)于表結(jié)構(gòu)設(shè)計(jì)的最佳實(shí)踐詳見這里 。

最新狀態(tài)數(shù)據(jù)

AP狀態(tài)

表名:wifi_ap_status

列類型列名類型示例備注
主鍵列pk0String1b5de627b4a25553baf1f72af9afb96dMD5(ap_mac),對(duì)ap_mac做MD5
值列ap_macString11:22:33:44:55:66AP MAC地址

report_timeInteger1537363646533UTC時(shí)間戳,毫秒

on_timeInteger1537363646533同上

sta_cntInteger10所連接終端數(shù)

cpu_usageInteger20CPU使用率

memory_usageInteger50內(nèi)存使用率

wan_recv_speedInteger817收數(shù)據(jù)速率,單位bps

wan_sent_speedInteger2411發(fā)數(shù)據(jù)速率,單位bps

代碼示例

下面將以 AP狀態(tài) 作為例子,給出全流程的代碼示例。

初始化

創(chuàng)建TableStore client

SyncClient syncClient = new SyncClient(                    "$endpoint",                    "$accessKeyId",                    "$accessKeySecret",                    "$instanceName"
            );

SyncClient對(duì)象為線程安全,如果使用Spring的話可以將其作為一個(gè)單例Bean注入到其他對(duì)象中使用

創(chuàng)建TableStore表

表的創(chuàng)建可以在控制臺(tái)上完成,也可以通過SDK完成,如果使用SDK的話代碼示例如下

創(chuàng)建AP狀態(tài)表
// 指定表名TableMeta tableMeta = new TableMeta("wifi_ap_status");// 指定主鍵列,根據(jù)上面的表結(jié)構(gòu)設(shè)計(jì),這邊只有pk0一個(gè)主鍵列tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema("pk0", PrimaryKeyType.STRING));
CreateTableRequest createTableRequest = new CreateTableRequest(tableMeta, new TableOptions(-1, 1));
syncClient.createTable(createTableRequest);

創(chuàng)建SearchIndex

與創(chuàng)建表相同,SearchIndex的創(chuàng)建可以通過控制臺(tái)完成,如果使用SDK的話,示例如下:

創(chuàng)建AP狀態(tài)SearchIndex
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ù)寫入

用戶只需使用原表格存儲(chǔ)的寫入功能將數(shù)據(jù)寫入即可,表格存儲(chǔ)內(nèi)部會(huì)自動(dòng)將數(shù)據(jù)導(dǎo)入SearchIndex,無(wú)需關(guān)心內(nèi)部實(shí)現(xiàn)。

PutRowRequest putRowRequest = new PutRowRequest();
RowPutChange rowPutChange = new RowPutChange("wifi_ap_status");
String apMac = "11:22:33:86:D9:E8";// 通過AP MAC計(jì)算MD5,防止產(chǎn)生數(shù)據(jù)熱點(diǎn),這邊使用了apache的commons-codec庫(kù)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ù)讀取

數(shù)據(jù)讀取分為兩種:
1.基于原生的表格存儲(chǔ)的主鍵獲取
2.基于SearchIndex功能獲取
下面對(duì)于這兩種不通模式的讀取分別舉例說(shuō)明

通過主鍵讀取

通過主鍵獲取AP狀態(tài)的話是直接從表格存儲(chǔ)的表中直接獲取的。也就是說(shuō),在通過主鍵獲取數(shù)據(jù)的時(shí)候是不需要通過SearchIndex功能的,代碼示例如下:

GetRowRequest getRowRequest = new GetRowRequest();
String apMac = "11:22:33:86:D9:E8";// 通過AP MAC計(jì)算MD5,防止產(chǎn)生數(shù)據(jù)熱點(diǎn),這邊使用了apache的commons-codec庫(kù)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() + ")");
}

通過SearchIndex功能讀取

為了方便描述,下面通過SQL(僅為表示具體需求,SearchIndex暫不支持SQL語(yǔ)句)+代碼的形式給出示例來(lái)描述我們的場(chǎng)景。

多維查詢

如果需要通過非主鍵列進(jìn)行多維查詢,我們可以使用syncClient的search方法,在上面的 例子 中,我們?yōu)閣ifi_ap_status表創(chuàng)建了SearchIndex,并且指定了索引列。
如果要實(shí)現(xiàn)下面的SQL:

SELECT*FROM  wifi_ap_statusWHERE ap_mac LIKE '%86:D9:E8%' AND sta_cnt >= 2

用java語(yǔ)言實(shí)現(xiàn)的話,代碼如下

SearchQuery searchQuery = new SearchQuery();// 使用BoolQuery來(lái)實(shí)現(xiàn)組合條件查詢,本例搜索了ap_mac包含86:D9:E8并且sta_cnt大于等于2的數(shù)據(jù)BoolQuery query = new BoolQuery();// 使用短語(yǔ)搜索模糊匹配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)建搜索請(qǐng)求SearchRequest searchRequest = new SearchRequest(        "wifi_ap_status", // 表格存儲(chǔ)表名
        "wifi_ap_status", // SearchIndex索引名
        searchQuery
);// 設(shè)置需要返回的表列SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet();// 設(shè)置返回所有列columnsToGet.setReturnAll(true);
searchRequest.setColumnsToGet(columnsToGet);// 搜索請(qǐng)求SearchResponse searchResponse = syncClient.search(searchRequest);
List rows = 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() + ")");
    }
}
排序

排序功能也是我們的常見需求,比如我們需要查看在某個(gè)條件下掛載終端數(shù)最多的幾個(gè)AP,如果用SQL語(yǔ)句描述的話如下:

SELECT*FROM  wifi_ap_statusWHERE ap_mac LIKE '%11:22:33%'ORDER BY sta_cnt DESC

如果用代碼表示的話,如下:

SearchQuery searchQuery = new SearchQuery();// 使用短語(yǔ)搜索模糊匹配ap_macMatchPhraseQuery macQuery = new MatchPhraseQuery();
macQuery.setFieldName("ap_mac");
macQuery.setText("11:22:33");
searchQuery.setQuery(macQuery);// 排序選項(xiàng),sta_cnt降序FieldSort staCntSorter = new FieldSort("sta_cnt");
staCntSorter.setOrder(SortOrder.DESC);
searchQuery.setSort(new Sort(Collections.singletonList(
        staCntSorter
)));// 構(gòu)建搜索請(qǐng)求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);// 搜索請(qǐng)求SearchResponse searchResponse = syncClient.search(searchRequest);
List rows = searchResponse.getRows();

到此,關(guān)于“基于TableStore的物聯(lián)網(wǎng)元數(shù)據(jù)管理怎么實(shí)現(xiàn)”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!


新聞標(biāo)題:基于TableStore的物聯(lián)網(wǎng)元數(shù)據(jù)管理怎么實(shí)現(xiàn)
文章來(lái)源:http://weahome.cn/article/gpijps.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部