什么是php网站开发美橙互联网站备案
什么是php网站开发,美橙互联网站备案,2345网址导航怎么卸载win10,查询网站收录背景
常见的企业级无线接入方案有两种#xff0c;分别被称作廋AP和胖AP。瘦AP#xff08;ACAP#xff09;架构为比较传统的企业级无线接入方案#xff0c;主要优点就是漫游体验好#xff0c;但是AC宕机的话会导致所属的AP全部无法工作。对于大型的办公场所#xff0c;漫…背景
常见的企业级无线接入方案有两种分别被称作廋AP和胖AP。瘦APACAP架构为比较传统的企业级无线接入方案主要优点就是漫游体验好但是AC宕机的话会导致所属的AP全部无法工作。对于大型的办公场所漫游的需求相对较弱新型的胖AP无AC不会因为AC宕机导致网络不可用 云端控制器架构成为了新兴的一种企业无线接入方案运维人员通过云端对AP进行监控与管理。
某公司拥有无线AP约10,000台、接入终端STA100,000个。设备以一定的周期上报其状态到云端云端将监控数据持久化后供用户查看。
业务描述
每个AP设备会以10s的周期上报其当前状态上报数据格式为json其格式如下 AP状态
{ap_mac: 11:22:33:86:D9:E8, // AP WAN口MAC地址AP设备唯一标识report_time: 1532315501985, // 上报时间戳毫秒on_time: 1531417181972, // 设备上线时间戳毫秒sta_cnt: 2, // 终端数量cpu_usage: 12, // CPU使用率memory_usage: 38, // CPU使用率wan_recv_speed: 280, // WAN口下行速率 单位bpswan_sent_speed: 45348, // WAN口上行速率 单位bps
}需求以及架构选型
需求
通过MAC地址查看每个AP最新的状态。用户需要在管理系统上对基于各种条件对设备进行查询。需要对AP的各种指标进行排序以便找出故障设备。 我们将上述的需求分为两种多维查询。排序。 基于这两大类需求我们给出如下的架构选型比较。
架构选型
针对这种IOT场景的设备状态监控数据下面针对几种常见方案做比较。
MySQL
将设备上报的状态数据直接写入MySQL并使用MySQL自带的查询、排序语句对数据进行分析这种架构最为简单用户运维成本较低。
这种架构仅仅适用于小规模量的数据在大规模数据的情况下MySQL的内部架构也导致了无法创建出一种万用的索引来满足多维查询的需求。并且MySQL底层使用的是B数作为存储结构会有随机写的问题写入性能较差。 MySQL在使用前必须指定表结构也就是说后续新增需求的话必须要修改表结构在数据量较大的情况下修改表结构很容易造成锁表导致线上故障。
MySQL 自建Elasticsearch
由于MySQL的检索能力较弱MySQL Elasticsearch也是业界比较常见的方案。用户将数据写入MySQL并使用binlog订阅工具如canal将数据异步写入Elasticsearch架构如下图所示 其中Canal Client需要用户自己编写与部署。相比单MySQL的架构该方案很好地解决了MySQL在多维查询和指定列排序能力弱的问题。但是带了的问题也比较多
Canal与Elasticsearch需要用户自己部署带来的运维成本也相对提升。Canal Client侧负责读取Canal传输过来MySQL增量改变数据数据的一致性是需要用户自己保证的。
使用表格存储的SearchIndex功能
表格存储底层存储使用的LSM模型很好地解决了MySQL写入性能差的问题特别适合IOT这种写多读少的场景。
用户将数据写入表格存储后系统内部会将数据异步同步到SearchIndex数据写入TableStore到数据可查约有毫秒到秒级别的延迟用户无需关注运维相关的问题数据一致性也有系统内部保证做到了开箱即用。
结论
基于上面的比较表格存储更适合存储AP的状态数据并且通过SearchIndex可以很容易地完成多维查询以及排序。简明的系统整体架构如下图所示 表结构设计
表格存储底层使用主键的第一列将数据均分到对应的分区上以达到负载均衡的目的。我们知道MAC地址的前3个字节为厂商码也就是说如果同一个厂家生产出来的设备MAC地址前3个字节大多会是相同的如果直接使用MAC地址做主键的话可能会导致数据热点所以我们推荐对MAC地址做MD5之后做第一列主键。关于表结构设计的最佳实践详见这里。
最新状态数据
AP状态
表名:wifi_ap_status
列类型列名类型示例备注主键列pk0String1b5de627b4a25553baf1f72af9afb96dMD5(ap_mac)对ap_mac做MD5值列ap_macString11:22:33:44:55:66AP MAC地址 report_timeInteger1537363646533UTC时间戳毫秒 on_timeInteger1537363646533同上 sta_cntInteger10所连接终端数 cpu_usageInteger20CPU使用率 memory_usageInteger50内存使用率 wan_recv_speedInteger817收数据速率单位bps wan_sent_speedInteger2411发数据速率单位bps
代码示例
下面将以AP状态作为例子给出全流程的代码示例。
初始化
创建TableStore client
SyncClient syncClient new SyncClient($endpoint,$accessKeyId,$accessKeySecret,$instanceName);
SyncClient对象为线程安全如果使用Spring的话可以将其作为一个单例Bean注入到其他对象中使用
创建TableStore表
表的创建可以在控制台上完成也可以通过SDK完成如果使用SDK的话代码示例如下
创建AP状态表
// 指定表名
TableMeta tableMeta new TableMeta(wifi_ap_status);
// 指定主键列根据上面的表结构设计这边只有pk0一个主键列
tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema(pk0, PrimaryKeyType.STRING));
CreateTableRequest createTableRequest new CreateTableRequest(tableMeta, new TableOptions(-1, 1));
syncClient.createTable(createTableRequest);
创建SearchIndex
与创建表相同SearchIndex的创建可以通过控制台完成如果使用SDK的话示例如下
创建AP状态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);
数据写入
用户只需使用原表格存储的写入功能将数据写入即可表格存储内部会自动将数据导入SearchIndex无需关心内部实现。
PutRowRequest putRowRequest new PutRowRequest();
RowPutChange rowPutChange new RowPutChange(wifi_ap_status);String apMac 11:22:33:86:D9:E8;
// 通过AP MAC计算MD5防止产生数据热点这边使用了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);
数据读取
数据读取分为两种 1.基于原生的表格存储的主键获取 2.基于SearchIndex功能获取 下面对于这两种不通模式的读取分别举例说明
通过主键读取
通过主键获取AP状态的话是直接从表格存储的表中直接获取的。也就是说在通过主键获取数据的时候是不需要通过SearchIndex功能的代码示例如下
GetRowRequest getRowRequest new GetRowRequest();
String apMac 11:22:33:86:D9:E8;
// 通过AP MAC计算MD5防止产生数据热点这边使用了apache的commons-codec库
String pk0 DigestUtils.md5Hex(apMac);
// 设置主键
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语句代码的形式给出示例来描述我们的场景。
多维查询
如果需要通过非主键列进行多维查询我们可以使用syncClient的search方法在上面的例子中我们为wifi_ap_status表创建了SearchIndex并且指定了索引列。 如果要实现下面的SQL
SELECT
*
FROM wifi_ap_status
WHERE ap_mac LIKE %86:D9:E8% AND sta_cnt 2
用java语言实现的话代码如下
SearchQuery searchQuery new SearchQuery();
// 使用BoolQuery来实现组合条件查询本例搜索了ap_mac包含86:D9:E8并且sta_cnt大于等于2的数据
BoolQuery query new BoolQuery();
// 使用短语搜索模糊匹配ap_mac
MatchPhraseQuery macQuery new MatchPhraseQuery();
macQuery.setFieldName(ap_mac);
macQuery.setText(86:D9:E8);
// 使用范围查询sta_cnt
RangeQuery staCntQuery new RangeQuery();
staCntQuery.setFieldName(sta_cnt);
staCntQuery.setFrom(ColumnValue.fromLong(2), true);
query.setMustQueries(Arrays.asList(macQuery,staCntQuery
));
searchQuery.setQuery(query);// 构建搜索请求
SearchRequest searchRequest new SearchRequest(wifi_ap_status, // 表格存储表名wifi_ap_status, // SearchIndex索引名searchQuery
);
// 设置需要返回的表列
SearchRequest.ColumnsToGet columnsToGet new SearchRequest.ColumnsToGet();
// 设置返回所有列
columnsToGet.setReturnAll(true);
searchRequest.setColumnsToGet(columnsToGet);// 搜索请求
SearchResponse searchResponse syncClient.search(searchRequest);
ListRow 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() ));}
}
排序
排序功能也是我们的常见需求比如我们需要查看在某个条件下挂载终端数最多的几个AP如果用SQL语句描述的话如下
SELECT
*
FROM wifi_ap_status
WHERE ap_mac LIKE %11:22:33%
ORDER BY sta_cnt DESC
如果用代码表示的话如下
SearchQuery searchQuery new SearchQuery();
// 使用短语搜索模糊匹配ap_mac
MatchPhraseQuery 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
)));// 构建搜索请求
SearchRequest searchRequest new SearchRequest(wifi_ap_status,wifi_ap_status,searchQuery
);
// 设置需要返回的表列
SearchRequest.ColumnsToGet columnsToGet new SearchRequest.ColumnsToGet();
// 设置返回所有列
columnsToGet.setReturnAll(true);
searchRequest.setColumnsToGet(columnsToGet);// 搜索请求
SearchResponse searchResponse syncClient.search(searchRequest);
ListRow rows searchResponse.getRows();
原文链接 本文为云栖社区原创内容未经允许不得转载。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/88700.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!