当前位置: 首页 > news >正文

【基于HBase和ElasticSearch构建大数据实时检索项目】

基于HBase和ElasticSearch构建大数据实时检索项目

    • 一、项目说明
    • 二、环境搭建
    • 三、编写程序
    • 四、测试流程

一、项目说明

  1. 利用HBase存储海量数据,解决海量数据存储和实时更新查询的问题;
  2. 利用ElasticSearch作为HBase索引,加快大数据集中实时查询数据;
  3. 使用到的大数据组件有:Hadoop-2.7.3、HBase-1.3.1、zookeeper-3.4.5、ElasticSearch-7.8.0
  4. 实验环境:
    虚拟机(操作系统CentOS7.6) + 个人PC(Windows)+ Eclipse或者Idea
  5. 大数据环境:3节点构成的全分布式环境
  6. 项目系统架构图如下:
    在这里插入图片描述
  7. 本项目是利用hbase和elasticsearch的API来完成数据的写入和检索

二、环境搭建

  1. 创建3台虚拟机,即3节点,主节点内存4G、从节点内存3G,可根据自己电脑配置来设置;
  2. 安装部署Hadoop全分布式,可参考:Hadoop2.7.3全分布式环境搭建
  3. 安装部署zookeeper全分布式,可参考:Zookeeper的集群安装
  4. 安装部署HBase全分布式,可参考:HBase几种安装方式,注意:需要先安装zookeeper并启动后,再安装和启动hbase
  5. 安装部署ElasticSearch集群,可参考:Linux下安装ElasticSearch集群,注意:需要使用es普通用户启动集群,安装成功后各个节点上启动

三、编写程序

本项目是在eclipse上编写

  1. 构建maven工程,配置settings.xml(可配置阿里或华为maven仓库),如下所示:

    <?xml version="1.0" encoding="utf-8"?>  
    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="         http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"><mirrors><mirror>  <id>nexus-aliyun</id>  <mirrorOf>central</mirrorOf>  <name>Nexus aliyun</name>  <url>http://maven.aliyun.com/nexus/content/groups/public/</url>  </mirror>  <mirror>  <id>net-cn</id>  <mirrorOf>central</mirrorOf>  <name>Nexus net</name>  <url>http://maven.net.cn/content/groups/public/</url>  </mirror>  </mirrors>  <profiles>  <profile>  <repositories>  <repository>  <id>nexus</id>  <name>local private nexus</name>  <url>http://maven.aliyun.com/nexus/content/groups/public/</url>  <releases>  <enabled>true</enabled>  </releases>  <snapshots>  <enabled>false</enabled>  </snapshots>  </repository>  </repositories>  <pluginRepositories>  <pluginRepository>  <id>nexus</id>  <name>local private nexus</name>  <url>http://maven.aliyun.com/nexus/content/groups/public/</url>  <releases>  <enabled>true</enabled>  </releases>  <snapshots>  <enabled>false</enabled>  </snapshots>  </pluginRepository>  </pluginRepositories>  </profile>  </profiles>  <activeProfiles>  <activeProfile>nexus</activeProfile>  </activeProfiles>  
    </settings>
    
  2. 添加依赖到pom.xml中,如下所示:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.bigdata</groupId><artifactId>realtimesearch</artifactId><version>1.0-SNAPSHOT</version><!-- Spring boot 父引用 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.4.0.RELEASE</version></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><!--仓库源--><repositories><repository><id>alimaven</id><name>aliyun maven</name><url>http://maven.aliyun.com/nexus/content/groups/public/</url><releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots></repository></repositories><dependencies><!-- Spring boot 核心web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 解决thymeleaf模板引擎对h5页面检查太严格问题 --><dependency><groupId>net.sourceforge.nekohtml</groupId><artifactId>nekohtml</artifactId><version>1.9.22</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!-- HBase --><dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-client</artifactId><version>1.3.1</version><exclusions><exclusion><artifactId>hadoop-mapreduce-client-core</artifactId><groupId>org.apache.hadoop</groupId></exclusion></exclusions></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-hdfs</artifactId><version>2.2.0</version></dependency><dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-protocol</artifactId><version>1.3.1</version></dependency><!-- ElasticSearch --><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.8.0</version></dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>transport</artifactId><version>7.8.0</version></dependency><!-- 解锁ES运行时没有对应方法的的错误 --><dependency><groupId>org.locationtech.spatial4j</groupId><artifactId>spatial4j</artifactId><version>0.6</version></dependency><!-- zookeeper --><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.9</version><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency><!-- 解决ES和HBase中 io.netty包冲突 --><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.16.Final</version></dependency><!-- json --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.13</version></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>jdk.tools</groupId><artifactId>jdk.tools</artifactId><version>1.8</version><scope>system</scope><systemPath>C:\Program Files\Java\jdk1.8.0_301\lib\tools.jar</systemPath></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.1</version><executions><execution><phase>compile</phase><goals><goal>compile</goal></goals></execution></executions></plugin></plugins><resources><resource><directory>src/main/resources</directory></resource></resources></build>
    </project>
    
  3. 新建data目录,并将测试数据放在该目录下,如下图所示:测试数据下载
    在这里插入图片描述

  4. 添加各类配置文件,如conf.propertiesapplication.propertieslog4j.propertieslog4j2.properties等,如下图所示:
    在这里插入图片描述

  5. 配置conf.properties,内容如下:

    	#原始数据路径inputPath =data/#HBase的配置#通过CloudTable服务列表获取的ZK连接地址,运行后可看到日志打印具体内网地址ZKServer=hostname01:2181,hostname02:2181,hostname03:2181#HBase表名tableName=PublicSecurity#HBase列族columnFamily1=BasiccolumnFamily2=OtherInfo#ElasticSearch的配置,如ES集群名称,虚拟机IP,默认端口clusterName=Es-clusterhostName=192.168.1.109tcpPort=9300indexName=publicsecuritytypeName=info
    
  6. 配置application.properties,内容如下:

       server.port=8084server.contextPath=/bigdata#web页面热布署spring.thymeleaf.cache=false#解决html5检查太严格问题spring.thymeleaf.mode = LEGACYHTML5
    
  7. 配置log4j.properties,内容如下:

      log4j.rootLogger=INFO,consolelog4j.appender.console=org.apache.log4j.ConsoleAppenderlog4j.appender.console.target=System.outlog4j.appender.console.layout=org.apache.log4j.PatternLayoutlog4j.appender.console.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
    
  8. 配置log4j2.properties,内容如下:

       name = PropertiesConfigproperty.filename = target/logs#appenders = console, file#配置值是appender的类型,并不是具体appender实例的nameappenders = rollingappender.rolling.type = RollingFileappender.rolling.name = RollingLogFileappender.rolling.fileName=${filename}/automationlogs.logappender.rolling.filePattern = ${filename}/automationlogs-%d{MM-dd-yy-HH-mm-ss}-%i.logappender.rolling.layout.type = PatternLayoutappender.rolling.layout.pattern=[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%nappender.rolling.policies.type = Policiesappender.rolling.policies.size.type = SizeBasedTriggeringPolicyappender.rolling.policies.size.size=100MBappender.rolling.strategy.type = DefaultRolloverStrategyappender.rolling.strategy.max = 5rootLogger.level = INFO,consolerootLogger.appenderRef.rolling.ref = rollingrootLogger.appenderRef.rolling.ref = RollingLogFile
    
  9. 编写读取配置文件的工具类ConstantUtil,代码如下:

    	package com.bigdata.utils;import org.apache.log4j.PropertyConfigurator;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.FileInputStream;import java.io.IOException;import java.util.Properties;/*** {@docRoot 用于读取配置内容}* @author suben*/public class ConstantUtil {public static final Properties PROPS = new Properties();public static final Logger LOG = LoggerFactory.getLogger(ConstantUtil.class);public static final String INPUT_PATH;public static final String ZK_SERVER;public static final String TABLE_NAME;public static final String COLUMN_FAMILY_1;public static final String COLUMN_FAMILY_2;public static final String INDEX_NAME;public static final String TYPE_NAME;//ES集群名,默认值elasticsearchpublic static final String CLUSTER_NAME;//ES集群中某个节点public static final String HOSTNAME;//ES连接端口号public static final int TCP_PORT;static {try {//加载日志配置PropertyConfigurator.configure(ConstantUtil.class.getClassLoader().getResource("log4j.properties").getPath());//加载连接配置PROPS.load(new FileInputStream(ConstantUtil.class.getClassLoader().getResource("conf.properties").getPath()));} catch (IOException e) {e.printStackTrace();}INPUT_PATH = PROPS.getProperty("inputPath");ZK_SERVER = PROPS.getProperty("ZKServer");TABLE_NAME = PROPS.getProperty("tableName");INDEX_NAME = PROPS.getProperty("indexName").toLowerCase();TYPE_NAME = PROPS.getProperty("typeName");COLUMN_FAMILY_1 = PROPS.getProperty("columnFamily1");COLUMN_FAMILY_2 = PROPS.getProperty("columnFamily2");CLUSTER_NAME = PROPS.getProperty("clusterName");HOSTNAME = PROPS.getProperty("hostName");TCP_PORT = Integer.valueOf(PROPS.getProperty("tcpPort"));}}
  10. 编写HBase工具类,代码如下:

    	package com.bigdata.utils;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.hbase.*;import org.apache.hadoop.hbase.client.*;import org.apache.hadoop.hbase.util.Bytes;import org.slf4j.Logger;import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class HBaseUtil {public static Admin admin = null;public static Configuration conf = null;public static Connection conn = null;private HashMap<String, Table> tables = null;private static final Logger LOG = ConstantUtil.LOG;public HBaseUtil() {this(ConstantUtil.ZK_SERVER);}public HBaseUtil(String zkServer) {init(zkServer);}private void ifNotConnTableJustConn(String tableName) {if (!tables.containsKey(tableName)) {this.addTable(tableName);}}public Table getTable(String tableName) {ifNotConnTableJustConn(tableName);return tables.get(tableName);}public void addTable(String tableName) {try {tables.put(tableName, conn.getTable(TableName.valueOf(tableName)));} catch (IOException e) {e.printStackTrace();}}public boolean put(String tableName, List<Put> putList) throws Exception {boolean res = false;ifNotConnTableJustConn(tableName);try {getTable(tableName).put(putList);res = true;} catch (IOException e) {e.printStackTrace();}return res;}public Result get(String tableName, String row) throws IOException {Result result = null;ifNotConnTableJustConn(tableName);Table newTable = getTable(tableName);Get get = new Get(Bytes.toBytes(row));try {result = newTable.get(get);KeyValue[] raw = result.raw();} catch (IOException e) {e.printStackTrace();}return result;}public boolean createTable(String tableName, String... columnFamilys) {boolean result = false;try {if (admin.tableExists(TableName.valueOf(tableName))) {LOG.info(tableName + "表已经存在!");} else {HTableDescriptor tableDesc = new HTableDescriptor(TableName.valueOf(tableName));for (String columnFamily : columnFamilys) {tableDesc.addFamily(new HColumnDescriptor(columnFamily.getBytes()));}admin.createTable(tableDesc);result = true;LOG.info(tableName + "表创建成功!");}} catch (IOException e) {e.printStackTrace();LOG.info(tableName + "表创建失败 !");}return result;}public boolean tableExists(String tableName) throws IOException {return admin.tableExists(TableName.valueOf(tableName));}public void disableTable(String tableName) throws IOException {if (tableExists(tableName)) {admin.disableTable(TableName.valueOf(tableName));}}/*** 删除表** @param tableName*/public void deleteTable(String tableName) throws IOException {disableTable(tableName);admin.deleteTable(TableName.valueOf(tableName));}/*** 查询所有表名** @return* @throws Exception*/public List<String> getALLTableName() throws Exception {ArrayList<String> tableNames = new ArrayList<String>();if (admin != null) {HTableDescriptor[] listTables = admin.listTables();if (listTables.length > 0) {for (HTableDescriptor tableDesc : listTables) {tableNames.add(tableDesc.getNameAsString());}}}return tableNames;}/*** 删除所有表,慎用!仅用于测试环境*/public void deleteAllTable() throws Exception {List<String> allTbName = getALLTableName();for (String s : allTbName) {LOG.info("Start delete table : " + s + "......");deleteTable(s);LOG.info("done delete table : " + s);}}/*** 初始化配置** @param zkServer*/public void init(String zkServer) {tables = new HashMap<String, Table>();conf = HBaseConfiguration.create();conf.set("hbase.zookeeper.quorum", zkServer);try {conn = ConnectionFactory.createConnection(conf);admin = conn.getAdmin();} catch (IOException e) {e.printStackTrace();}}/*** 清理所有连接** @throws IOException*/public void clear() throws IOException {for (Map.Entry<String, Table> m : tables.entrySet()) {m.getValue().close();}admin.close();conn.close();conf.clear();}/*** 关卡登记信息bayonet:姓名,身份证号,年龄,性别,关卡号,日期时间,通关形式* 住宿登记信息hotel:姓名,身份证号,年龄,性别,起始日期,结束日期,同行人* 网吧登记信息internet:姓名,身份证号,年龄,性别,网吧名,日期,逗留时长*///用于提前建好表和列族public static void preDeal() throws Exception {HBaseUtil hBaseUtils = new HBaseUtil();hBaseUtils.createTable(ConstantUtil.TABLE_NAME, ConstantUtil.COLUMN_FAMILY_1, ConstantUtil.COLUMN_FAMILY_2);}//测试public static void test() throws Exception {HBaseUtil hBaseUtils = new HBaseUtil();long startTime = System.currentTimeMillis();String tb = "testTb";String colFamily = "info";String col = "name";String row = "100000";String value = "张三";hBaseUtils.createTable(tb, colFamily);List<Put> listPut = new ArrayList<>();Put put = new Put(Bytes.toBytes(row));put.addColumn(Bytes.toBytes(colFamily), Bytes.toBytes(col), Bytes.toBytes(value));listPut.add(put);hBaseUtils.put(tb, listPut);Result res = hBaseUtils.get("testTb", "100000");List<Cell> list = res.getColumnCells(Bytes.toBytes("info"), Bytes.toBytes("name"));for (Cell c : list) {LOG.info(Bytes.toString(CellUtil.cloneFamily(c)));LOG.info(Bytes.toString(CellUtil.cloneQualifier(c)));LOG.info(Bytes.toString(CellUtil.cloneValue(c)));}long endTime = System.currentTimeMillis();float seconds = (endTime - startTime) / 1000F;LOG.info("  耗时" + Float.toString(seconds) + " seconds.");}public static void main(String[] args) throws Exception {test();preDeal();}}
  11. 编写ElasticSearch工具类,代码如下:

    			package com.bigdata.utils;import com.alibaba.fastjson.JSONObject;import org.apache.lucene.search.TotalHits;import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;//import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;import org.elasticsearch.action.index.IndexRequestBuilder;import org.elasticsearch.action.index.IndexResponse;import org.elasticsearch.action.search.SearchRequestBuilder;import org.elasticsearch.action.search.SearchResponse;import org.elasticsearch.action.support.master.AcknowledgedResponse;import org.elasticsearch.client.IndicesAdminClient;import org.elasticsearch.client.transport.TransportClient;import org.elasticsearch.common.settings.Settings;import org.elasticsearch.common.transport.TransportAddress;import org.elasticsearch.common.xcontent.XContentBuilder;import org.elasticsearch.common.xcontent.XContentType;import org.elasticsearch.index.query.QueryBuilder;import org.elasticsearch.index.query.QueryBuilders;import org.elasticsearch.search.SearchHit;import org.elasticsearch.search.SearchHits;import org.elasticsearch.transport.client.PreBuiltTransportClient;import org.slf4j.Logger;import java.io.IOException;import java.net.InetAddress;import java.net.UnknownHostException;import java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.Set;import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;public class ElasticSearchUtil {//构建Settings对象private static Settings settings = Settings.builder().put("cluster.name", ConstantUtil.CLUSTER_NAME).put("client.transport.sniff", false).build();//TransportClient对象,用于连接ES集群private volatile TransportClient client;private final static Logger LOG = ConstantUtil.LOG;public ElasticSearchUtil() {init();}/*** 同步synchronized(*.class)代码块的作用和synchronized static方法作用一样,* 对当前对应的*.class进行持锁,static方法和.class一样都是锁的该类本身,同一个监听器** @return* @throws UnknownHostException*/public TransportClient getClient() {if (client == null) {synchronized (TransportClient.class) {try {client = new PreBuiltTransportClient(settings).addTransportAddress(new TransportAddress(InetAddress.getByName(ConstantUtil.HOSTNAME), ConstantUtil.TCP_PORT));} catch (UnknownHostException e) {e.printStackTrace();}}}return client;}/*** 获取索引管理的IndicesAdminClient*/public IndicesAdminClient getAdminClient() {return getClient().admin().indices();}/*** 判定索引是否存在** @param indexName* @return*/public boolean isExistsIndex(String indexName) {IndicesExistsResponse response = getAdminClient().prepareExists(indexName).get();return response.isExists() ? true : false;}/*** 创建索引** @param indexName* @return*/public boolean createIndex(String indexName) {CreateIndexResponse createIndexResponse = getAdminClient().prepareCreate(indexName.toLowerCase()).get();return createIndexResponse.isAcknowledged() ? true : false;}/*** 删除索引** @param indexName* @return*/public boolean deleteIndex(String indexName) {AcknowledgedResponse deleteResponse = getAdminClient().prepareDelete(indexName.toLowerCase()).execute().actionGet();return deleteResponse.isAcknowledged() ? true : false;}/*** 为索引indexName设置mapping** @param indexName* @param typeName* @param mapping*/public void setMapping(String indexName, String typeName, String mapping) {getAdminClient().preparePutMapping(indexName).setType(typeName).setSource(mapping, XContentType.JSON).get();}/*** 创建文档,相当于往表里面insert一行数据** @param indexName* @param typeName* @param id* @param document* @return* @throws IOException*/public long addDocument(String indexName, String typeName, String id, Map<String, Object> document) throws IOException {Set<Map.Entry<String, Object>> documentSet = document.entrySet();IndexRequestBuilder builder = getClient().prepareIndex(indexName, typeName, id);XContentBuilder xContentBuilder = jsonBuilder().startObject();for (Map.Entry e : documentSet) {xContentBuilder = xContentBuilder.field(e.getKey().toString(), e.getValue());}IndexResponse response = builder.setSource(xContentBuilder.endObject()).get();return response.getVersion();}public List<Map<String, Object>> queryStringQuery(String text) {List<Map<String, Object>> resListMap = null;QueryBuilder match = QueryBuilders.queryStringQuery(text);SearchRequestBuilder search = getClient().prepareSearch().setQuery(match); //分页 可选//搜索返回搜索结果SearchResponse response = search.get();//命中的文档SearchHits hits = response.getHits();//命中总数TotalHits total = hits.getTotalHits();SearchHit[] hitAarr = hits.getHits();//循环查看命中值resListMap = new ArrayList<Map<String, Object>>();for (SearchHit hit : hitAarr) {//文档元数据String index = hit.getIndex();//文档的_source的值Map<String, Object> resultMap = hit.getSourceAsMap();resListMap.add(resultMap);}return resListMap;}private void init() {try {client = new PreBuiltTransportClient(settings).addTransportAddress(new TransportAddress(InetAddress.getByName(ConstantUtil.HOSTNAME), ConstantUtil.TCP_PORT));} catch (UnknownHostException e) {e.printStackTrace();}}//用于提前建好索引,相当于关系型数据库当中的数据库public static void preDealCreatIndex() {ElasticSearchUtil esUtils = new ElasticSearchUtil();LOG.info("start create index..............");esUtils.createIndex(ConstantUtil.INDEX_NAME);LOG.info("finished create index !");}/*** 关卡登记信息bayonet:姓名,身份证号,年龄,性别,关卡号,日期时间,通关形式* 住宿登记信息hotel:姓名,身份证号,年龄,性别,起始日期,结束日期,同行人* 网吧登记信息internet:姓名,身份证号,年龄,性别,网吧名,日期,逗留时长* name,id,age,gender,* hotelAddr,hotelInTime,hotelOutTime,acquaintancer,* barAddr,internetDate,timeSpent,* bayonetAddr,crossDate,tripType*/public static void preDealSetMapping() {JSONObject mappingTypeJson = new JSONObject();JSONObject propertiesJson = new JSONObject();JSONObject idJson = new JSONObject();idJson.put("type", "keyword");idJson.put("store", "true");propertiesJson.put("id", idJson);JSONObject nameJson = new JSONObject();nameJson.put("type", "keyword");propertiesJson.put("name", nameJson);JSONObject uidJson = new JSONObject();uidJson.put("type", "keyword");uidJson.put("store", "false");propertiesJson.put("uid", uidJson);JSONObject hotelAddr = new JSONObject();hotelAddr.put("type", "text");propertiesJson.put("address", hotelAddr);JSONObject happenedDate = new JSONObject();happenedDate.put("type", "date");happenedDate.put("format", "yyyy-MM-dd");propertiesJson.put("happenedDate", happenedDate);JSONObject endDate = new JSONObject();endDate.put("type", "date");endDate.put("format", "yyyy-MM-dd");propertiesJson.put("endDate", endDate);JSONObject acquaintancer = new JSONObject();acquaintancer.put("type", "keyword");propertiesJson.put("acquaintancer", acquaintancer);mappingTypeJson.put("properties", propertiesJson);LOG.info("start set mapping to " + ConstantUtil.INDEX_NAME + " " + ConstantUtil.TYPE_NAME + " .....");LOG.info(mappingTypeJson.toString());ElasticSearchUtil esUtils = new ElasticSearchUtil();esUtils.setMapping(ConstantUtil.INDEX_NAME, ConstantUtil.TYPE_NAME, mappingTypeJson.toString());LOG.info("set mapping done!!!");}//用于测试public static void test() {String index = "esindex";System.out.println("createIndex..............");ElasticSearchUtil esUtils = new ElasticSearchUtil();esUtils.createIndex(index);System.out.println("createIndex done!!!!!!!!!!!");System.out.println("isExists = " + esUtils.isExistsIndex(index));System.out.println("deleteIndex...............");esUtils.deleteIndex(index);System.out.println("deleteIndex done!!!!");}public static void main(String[] args) throws IOException {preDealCreatIndex();preDealSetMapping();test();}}
    
  12. 编写数据写入HBase和ES的实现类,代码如下:

    		package com.bigdata.insert;import org.apache.hadoop.hbase.client.Put;import org.apache.hadoop.hbase.util.Bytes;import com.bigdata.utils.ConstantUtil;import com.bigdata.utils.ElasticSearchUtil;import com.bigdata.utils.HBaseUtil;import java.io.BufferedReader;import java.io.File;import java.io.FileReader;import java.util.*;/*** 读取本地文件并解析数据,之后插入HBase、ElasticSearch*/public class LoadDataToHBaseAndES {private HBaseUtil hBaseUtil;private ElasticSearchUtil elasticSearchUtil;public LoadDataToHBaseAndES() {}/*** 关卡登记信息bayonet:姓名,身份证号,年龄,性别,关卡号,日期时间,通关形式* 住宿登记信息hotel:姓名,身份证号,年龄,性别,起始日期,结束日期,同行人* 网吧登记信息internet:姓名,身份证号,年龄,性别,网吧名,日期,逗留时长* name,uid,age,gender,* hotelAddr,happenedDate,endDate,acquaintancer,* barAddr,happenedDate,duration,* bayonetAddr,happenedDate,tripType*/public void insert() throws Exception {hBaseUtil = new HBaseUtil();elasticSearchUtil = new ElasticSearchUtil();String filePath = ConstantUtil.INPUT_PATH;File dir = new File(filePath);File[] files = dir.listFiles();if (files != null) {for (File file : files) {if (file.isDirectory()) {System.out.println(file.getName() + "This is a directory!");} else {//住宿登记信息if (file.getName().contains("hotel")) {BufferedReader reader = null;reader = new BufferedReader(new FileReader(filePath + file.getName()));String tempString = null;while ((tempString = reader.readLine()) != null) {//Blank line judgmentif (!tempString.isEmpty()) {List<Put> putList = new ArrayList<Put>();String[] elements = tempString.split(",");//生成不重复用户ID,String id = UUID.randomUUID().toString();Put put = new Put(Bytes.toBytes(id));//将数据添加至hbase库put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("name"), Bytes.toBytes(elements[0]));put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("uid"), Bytes.toBytes(elements[1]));put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("age"), Bytes.toBytes(elements[2]));put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("gender"), Bytes.toBytes(elements[3]));put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("event"), Bytes.toBytes("hotel"));put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("address"), Bytes.toBytes(elements[4]));put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("happenedDate"), Bytes.toBytes(elements[5]));put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("endDate"), Bytes.toBytes(elements[6]));put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("acquaintancer"), Bytes.toBytes(elements[7]));putList.add(put);ConstantUtil.LOG.info("hotel_info start putting to HBase ....:" + id + " " + tempString);hBaseUtil.put(ConstantUtil.TABLE_NAME, putList);//将数据添加至ES库Map<String, Object> esMap = new HashMap<String, Object>();esMap.put("id", id);esMap.put("name", elements[0]);esMap.put("uid", elements[1]);esMap.put("address", elements[4]);esMap.put("happenedDate", elements[5]);esMap.put("endDate", elements[6]);esMap.put("acquaintancer", elements[7]);elasticSearchUtil.addDocument(ConstantUtil.INDEX_NAME, ConstantUtil.TYPE_NAME, id, esMap);ConstantUtil.LOG.info("start add document to ES..." + ConstantUtil.INDEX_NAME + " " + ConstantUtil.TYPE_NAME + " " + id + " " + esMap);}}reader.close();}//网吧登记信息else if (file.getName().contains("internet")) {BufferedReader reader = null;reader = new BufferedReader(new FileReader(filePath + file.getName()));String tempString = null;while ((tempString = reader.readLine()) != null) {//Blank line judgmentif (!tempString.isEmpty()) {List<Put> putList = new ArrayList<Put>();String[] elements = tempString.split(",");//生成不重复用户ID,String id = UUID.randomUUID().toString();Put put = new Put(Bytes.toBytes(id));//将数据添加至hbase库put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("name"), Bytes.toBytes(elements[0]));put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("uid"), Bytes.toBytes(elements[1]));put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("age"), Bytes.toBytes(elements[2]));put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("gender"), Bytes.toBytes(elements[3]));put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("event"), Bytes.toBytes("internetBar"));put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("address"), Bytes.toBytes(elements[4]));put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("happenedDate"), Bytes.toBytes(elements[5]));put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("duration"), Bytes.toBytes(elements[6]));putList.add(put);ConstantUtil.LOG.info("internet_info start putting to HBase ... :" + id + " " + tempString);hBaseUtil.put(ConstantUtil.TABLE_NAME, putList);//将数据添加至ES库Map<String, Object> esMap = new HashMap<String, Object>();esMap.put("id", id);esMap.put("name", elements[0]);esMap.put("uid", elements[1]);esMap.put("address", elements[4]);esMap.put("happenedDate", elements[5]);elasticSearchUtil.addDocument(ConstantUtil.INDEX_NAME, ConstantUtil.TYPE_NAME, id, esMap);ConstantUtil.LOG.info("start add document to ES..." + ConstantUtil.INDEX_NAME + " " + ConstantUtil.TYPE_NAME + " " + id + " " + esMap);}}reader.close();}//关卡登记信息else if (file.getName().contains("bayonet")) {BufferedReader reader = null;reader = new BufferedReader(new FileReader(filePath + file.getName()));String tempString = null;while ((tempString = reader.readLine()) != null) {//Blank line judgmentif (!tempString.isEmpty()) {List<Put> putList = new ArrayList<Put>();String[] elements = tempString.split(",");//生成不重复用户ID,String id = UUID.randomUUID().toString();Put put = new Put(Bytes.toBytes(id));//将数据添加至hbase库put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("name"), Bytes.toBytes(elements[0]));put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("uid"), Bytes.toBytes(elements[1]));put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("age"), Bytes.toBytes(elements[2]));put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("gender"), Bytes.toBytes(elements[3]));put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("event"), Bytes.toBytes("bayonet"));put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("address"), Bytes.toBytes(elements[4]));put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("happenedDate"), Bytes.toBytes(elements[5]));put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("tripType"), Bytes.toBytes(elements[6]));putList.add(put);hBaseUtil.put(ConstantUtil.TABLE_NAME, putList);ConstantUtil.LOG.info("bayonet_info start putting to HBase....:" + id + " " + tempString);//将数据添加至ES库Map<String, Object> esMap = new HashMap<String, Object>();esMap.put("id", id);esMap.put("name", elements[0]);esMap.put("uid", elements[1]);esMap.put("address", elements[4]);esMap.put("happenedDate", elements[5]);elasticSearchUtil.addDocument(ConstantUtil.INDEX_NAME, ConstantUtil.TYPE_NAME, id, esMap);ConstantUtil.LOG.info("start add document to ES..." + ConstantUtil.INDEX_NAME + " " + ConstantUtil.TYPE_NAME + " " + id + " " + esMap);}}reader.close();}//数据描述文件跳过else {continue;}}}ConstantUtil.LOG.info("load and insert done !!!!!!!!!!!!!!!!!!");}}public static void start() throws Exception {LoadDataToHBaseAndES load2DB = new LoadDataToHBaseAndES();load2DB.insert();}public static void main(String[] args) throws Exception {start();}}
    
  13. 编写Query查询类,代码如下:

       package com.bigdata.query;import com.alibaba.fastjson.JSONObject;import com.bigdata.utils.ConstantUtil;import com.bigdata.utils.ElasticSearchUtil;import com.bigdata.utils.HBaseUtil;import org.apache.hadoop.hbase.Cell;import org.apache.hadoop.hbase.CellUtil;import org.apache.hadoop.hbase.client.Result;import org.apache.hadoop.hbase.util.Bytes;import java.io.IOException;import java.util.List;import java.util.Map;/**** 搜索逻辑是先搜索ElasticSearch,再查HBase*/public class Query {private HBaseUtil hBaseUtil = new HBaseUtil();private ElasticSearchUtil elasticSearchUtil = new ElasticSearchUtil();private JSONObject result = new JSONObject();private JSONObject tmpJS = new JSONObject();public String query(String target) {result.clear();tmpJS.clear();long startTime = System.currentTimeMillis();List<Map<String, Object>> listMap = elasticSearchUtil.queryStringQuery(target);long endTime = System.currentTimeMillis();float seconds = (endTime - startTime) / 1000F;ConstantUtil.LOG.info("ElasticSearch查询耗时" + Float.toString(seconds) + " seconds.");for (Map<String, Object> m : listMap) {String id = m.get("id").toString();JSONObject tmpJS = new JSONObject();tmpJS.put("id", id);Result res = null;try {long s1 = System.currentTimeMillis();res = hBaseUtil.get(ConstantUtil.TABLE_NAME, id);long e1 = System.currentTimeMillis();float se1 = (e1 - s1) / 1000F;ConstantUtil.LOG.info("HBase查询耗时" + Float.toString(se1) + " seconds.");Cell[] cells = res.rawCells();for (Cell cell : cells) {String col = Bytes.toString(CellUtil.cloneQualifier(cell));System.out.println(col);String value = Bytes.toString(CellUtil.cloneValue(cell));System.out.println(value);tmpJS.put(col, value);}result.put(id, tmpJS);} catch (IOException e) {e.printStackTrace();result.put(id, "查询失败!");}}return result.toString();}public static void main(String[] args) throws Exception {Query query = new Query();long startTime = System.currentTimeMillis();System.out.println(query.query("100004"));long endTime = System.currentTimeMillis();float seconds = (endTime - startTime) / 1000F;ConstantUtil.LOG.info("  耗时" + Float.toString(seconds) + " seconds.");}}
  14. 编写ManagerQuery查询类,代码如下:

       package com.bigdata.manager;import org.springframework.stereotype.Component;import com.bigdata.query.Query;@Componentpublic class ManagerQuery {private static Query query = new Query();public static String getQueryResult(String target) {try {String result =  query.query(target);System.out.println(result);return result;} catch (Exception e) {e.printStackTrace();return "查询出现异常,请通知研发人员!";}}public static void main(String[] args) {String target = "牧之桃";String result = ManagerQuery.getQueryResult(target);System.out.println(result);}}
    
  15. 编写SearchService服务类(可参考SpringMVC代码写作),代码如下:

       package com.bigdata.service;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;import org.springframework.context.annotation.ComponentScan;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import com.bigdata.manager.ManagerQuery;@RestController@EnableAutoConfiguration@ComponentScan(basePackages = {"com.bigdata"})public class SearchService {@RequestMapping("/search")public String search(String target) {try {return ManagerQuery.getQueryResult(target);} catch (Exception e) {e.printStackTrace();}return "不小心出错了!";}// 主方法,像一般的Java类一般去右击run as application时候,执行该方法public static void main(String[] args) throws Exception {SpringApplication.run(SearchService.class, args);}}
  16. 编写SearchController控制类(可参考SpringMVC代码写作),代码如下:

       package com.bigdata.controller;import org.springframework.boot.SpringApplication;import org.springframework.stereotype.Controller;import org.springframework.ui.ModelMap;import org.springframework.web.bind.annotation.RequestMapping;/*** 注解声明,该类为Controller类 并自动加载所需要的其它类*/@Controllerpublic class SearchController {@RequestMapping("/index")String testdo(ModelMap map) {//这里返回HTML页面return "index_search";}// 主方法,像一般的Java类一般去右击run as application时候,执行该方法public static void main(String[] args) {SpringApplication.run(SearchController.class, args);}}
  17. 编写ApplicationBootSystem启动类,代码如下:

    package com.bigdata.boot;import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.ComponentScan;/*** 根启动类*/
    @SpringBootApplication
    @ComponentScan(basePackages = "com.bigdata")
    public class ApplicationBootSystem {public static void main(String[] args) {SpringApplication.run(ApplicationBootSystem.class, args);}
    }
    
  18. 新建static并在其下新建plugins,并将bootstrap-3.3.7和bootstrap-table包复制到该目录下
    在这里插入图片描述

  19. 新建template目录,并在其下面新建index_search.html文件
    在这里插入图片描述
    具体代码如下:

     	<!DOCTYPE html>
    <html lang="en">
    <head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags --><title>Realtime Search</title><!-- Bootstrap --><link href="plugins/bootstrap-3.3.7/css/bootstrap.min.css" rel="stylesheet"><link href="plugins/bootstrap-table/bootstrap-table.min.css" rel="stylesheet"><!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --><!-- WARNING: Respond.js doesn't work if you view the page via file:// --><!--[if lt IE 9]><script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>;<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>;<![endif]-->
    </head>
    <body>
    <div class="container"><div class="row"><!-- onsubmit设置成return false,不再显式提交form --><div class="col-md-8 col-md-offset-2 text-center"onsubmit="return false"><form class="form-inline"><div class="form-group"><label for="target">请输入条件</label> <input type="text"class="form-control" id="target" name="target" placeholder="请输入条件"></div><button type="submit" id="submit" class="btn btn-primary">搜一下</button></form></div></div><!-- 在下一行中,添加一个bs系统自带的表格 --><div class="row"><table id="table"></table></div>
    </div>
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="http://code.jquery.com/jquery-1.12.1.min.js" ;></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="plugins/bootstrap-3.3.7/js/bootstrap.min.js"></script>
    <!-- 加入bootstrap table依赖 -->
    <script src="plugins/bootstrap-table/bootstrap-table.min.js"></script>
    <script src="plugins/bootstrap-table/bootstrap-table-locale-all.min.js"></script>
    <script type="text/javascript">$(function () {<!--初始化表格的样式 -->$('#table').bootstrapTable({columns: [{field: 'id',title: '记录id',formatter: function (value, row, index) {var a = "";if (value == $("#target").val()) {a = '<span style="color:#5858FA">' + value + '</span>';} else {a = '<span style="color#190707">' + value + '</span>';}return a;}},{field: 'name',title: '姓名',formatter: function (value, row, index) {var a = "";if (value == $("#target").val()) {a = '<span style="color:#5858FA">' + value + '</span>';} else {a = '<span style="color#190707">' + value + '</span>';}return a;}}, {field: 'uid',title: '用户id',formatter: function (value, row, index) {var a = "";if (value == $("#target").val()) {a = '<span style="color:#5858FA">' + value + '</span>';} else {a = '<span style="color#190707">' + value + '</span>';}return a;}}, {field: 'age',title: '年龄',formatter: function (value, row, index) {var a = "";if (value == $("#target").val()) {a = '<span style="color:#5858FA">' + value + '</span>';} else {a = '<span style="color#190707">' + value + '</span>';}return a;}}, {field: 'gender',title: '性别',formatter: function (value, row, index) {var a = "";if (value == $("#target").val()) {a = '<span style="color:#5858FA">' + value + '</span>';} else {a = '<span style="color#190707">' + value + '</span>';}return a;}}, {field: 'event',title: '事件',formatter: function (value, row, index) {var a = "";if (value == $("#target").val()) {a = '<span style="color:#5858FA">' + value + '</span>';} else {a = '<span style="color#190707">' + value + '</span>';}return a;}},{field: 'address',title: '地址',formatter: function (value, row, index) {var a = "";if (value == $("#target").val()) {a = '<span style="color:#5858FA">' + value + '</span>';} else {a = '<span style="color#190707">' + value + '</span>';}return a;}}, {field: 'happenedDate',title: '发生时间',formatter: function (value, row, index) {var a = "";if (value == $("#target").val()) {a = '<span style="color:#5858FA">' + value + '</span>';} else {a = '<span style="color#190707">' + value + '</span>';}return a;}}, {field: 'acquaintancer',title: '同行人',formatter: function (value, row, index) {var a = "";if (value == $("#target").val()) {a = '<span style="color:#5858FA">' + value + '</span>';} else {a = '<span style="color#190707">' + value + '</span>';}return a;}},{field: 'endDate',title: '结束时间',formatter: function (value, row, index) {var a = "";if (value == $("#target").val()) {a = '<span style="color:#5858FA">' + value + '</span>';} else {a = '<span style="color#190707">' + value + '</span>';}return a;}}]});//为submit按钮绑定click事件,填充点击查询后的数据查询$("#submit").click(function () {$.ajax({url: '/bigdata/search',data: "target=" + $("#target").val(),cache: false,//false是不缓存,true为缓存async: true,//true为异步,false为同步beforeSend: function () {//请求前},success: function (result) {try {var resultArray = new Array();js = JSON.parse(result);for (var p in js) {resultArray.push(js[p])console.log(js[p]);}console.log(resultArray);$("#table").bootstrapTable('load', resultArray);} catch (e) {window.alert(result);$("#table").bootstrapTable('load', [{"result": "什么也没有找到"}]);}},complete: function () {//请求结束时},error: function () {//请求失败时}})});});</script>
    </body>
    </html>
    
  20. 写完成后,项目结构如下所示
    在这里插入图片描述

四、测试流程

  1. 先执行HBaseUtil工具类main方法,完成HBase测试表和目标表的创建,验证程序和hbase的连通性;

  2. 再执行ElasticSearch工具类main方法,完成ElasticSearch测试表和目标表的创建,验证程序和ElasticSearch的连通性;

  3. 再执行LoadDataToHBaseAndES类,完成数据写入HBase和ElasticSearch中;

  4. 再执行ApplicationBootSystem启动类,启动springboot入口程序;

  5. 最后打开浏览器输入:http://localhost:8084/bigdata/index,在打开的界面中的搜索框输入查询关键字,如输入3,点击【搜一下】按钮,正常情况下会看到如下结果:
    在这里插入图片描述

  6. 尝试输入不同的条件,查看到不同的结果,注意: 需要观察检索的实时性或者速度是很快的。另外,还可以尝试下修改测试数据集,使得其数据量变得更大些,然后再查看其检索速度,读者可以自行尝试。

相关文章:

【基于HBase和ElasticSearch构建大数据实时检索项目】

基于HBase和ElasticSearch构建大数据实时检索项目 一、项目说明二、环境搭建三、编写程序四、测试流程 一、项目说明 利用HBase存储海量数据&#xff0c;解决海量数据存储和实时更新查询的问题&#xff1b;利用ElasticSearch作为HBase索引&#xff0c;加快大数据集中实时查询数…...

ProComponent 用法学习

相信很多同学都用过 Ant Design 这一 react 著名组件库&#xff0c;而 ProComponents 则是在 antd 之上进行封装的页面级组件库&#xff08;指一个组件就可以搞定一个页面&#xff09;。它同时也是 Ant Design Pro 中后台框架所用的主要组件库。如果你手上有要用 react 开发的中…...

巨人互动|Google海外户Google Analytics的优缺点是什么?

Google Analytics是一个由谷歌开发的网站分析工具&#xff0c;旨在帮助网站和移动应用程序运营者收集和分析数据&#xff0c;以更好地了解用户行为和改进业务。虽然Google Analytics具有许多优势&#xff0c;但也存在一些缺点。在本文中&#xff0c;我们将探讨Google Analytics…...

MySQL数据库的操作

MySQL 连接服务器 库的操作创建数据库数据库删除查看数据库进入数据库查看所在的数据库修改数据库显示创建语句查看连接情况 表的操作创建表查看数据库所有的表查看表的详细信息查看创建表时的详细信息删除表修改表名向表中插入数据在表结构中新增一列对表结构数据的修改删除表…...

人工智能行业岗位一览

人工智能行业的岗位薪资高、待遇好、涨薪快已经是公开的事实&#xff0c;那么在人工智能行业中具体有哪些职业岗位呢&#xff1f;对于普通人来说&#xff0c;想要入行人工智能又有哪些机会呢&#xff1f; 下面是人工智能领域中的一部分职业岗位&#xff0c;随着技术的不断发展&…...

《Linux运维实战:Docker基础总结》

一、简介 1、docker的基本结构是什么&#xff0c;包含哪些组件&#xff1f; docker的基本机构是c/s模式&#xff0c;即客户端/服务端模式。 由docker客户端和docker守护进程组成。docker客户端通过命令行或其它工具使用docker sdk与docker守护进程通信&#xff0c;发送容器管理…...

Clash 意外退出后 chrome / google 谷歌 浏览器无法连接互联网

解决方案&#xff1a; 以管理员模式打开命令行&#xff0c;输入&#xff1a;netsh winsock reset &#xff0c;然后重启电脑 如果还不行的话&#xff0c; 在 chromevs中选中 设置>隐私和安全>安全>使用安全 dns> 使用您当前的服务提供商 即可...

89 | Python人工智能篇 —— 深度学习算法 Keras 实现 MNIST分类

本教程将带您深入探索Keras,一个开源的深度学习框架,用于构建人工神经网络模型。我们将一步步引导您掌握Keras的核心概念和基本用法,学习如何构建和训练深度学习模型,以及如何将其应用于实际问题中。 文章目录 Keras 构建实际mnist图像分类案例.1. 介绍2. 环境搭建3. 数据准…...

每天一道leetcode:剑指 Offer 32 - III. 从上到下打印二叉树 III(中等广度优先遍历)

今日份题目&#xff1a; 请实现一个函数按照之字形顺序打印二叉树&#xff0c;即第一行按照从左到右的顺序打印&#xff0c;第二层按照从右到左的顺序打印&#xff0c;第三行再按照从左到右的顺序打印&#xff0c;其他行以此类推。 示例 给定二叉树: [3,9,20,null,null,15,7…...

day10 快速排序 方法重载 和 方法递推

方法重载 斐波拉契数列问题 使用重载思想解决 public static int method(int n){if (n 2 ){return 1 ;}return (n-1)*2method(n-1);}public static int f(int n){if (n 1){return 1;}if (n 2){return 2;}return f(n-1)f(n-2);} 快速排序 思维很简单&#xff0c;类似二…...

Qt 6. 其他类调用Ui中的控件

1. 把主类指针this传给其他类&#xff0c;tcpClientSocket new TcpClient(this); //ex2.cpp #include "ex2.h" #include "ui_ex2.h"Ex2::Ex2(QWidget *parent): QDialog(parent), ui(new Ui::Ex2) {ui->setupUi(this);tcpClientSocket new TcpClient…...

PHP 的不同版本(src 版、nts 版和 win 版)之间的区别和共同点。

在下载php时会有很多版本供我们选择&#xff0c;PHP 的不同版本&#xff08;src 版、nts 版和 win 版&#xff09;之间的区别又是什么呢。 src 版本&#xff1a;src 版本指的是 PHP 的源代码版本&#xff0c;您需要自行编译并安装它。这个版本通常用于自定义编译、开发环境和高…...

3 vue的if语法

vue的if语法是相当于一个标签的属性来写进去的&#xff0c;比如说<h1 v-if“”>。要注意的是if语句里可以自动从数据层取值的&#xff0c;比如<h1 v-if"message">&#xff0c;这里就会自动把key为message的值取过来&#xff0c;而如果要传一个字符串&…...

python基础3——流程控制

文章目录 一、操作符1.1 比较操作符1.2 逻辑操作符1.3 成员操作符1.4 身份操作符 二、流程控制2.1 条件判断2.2 循环语句2.2.1 for循环2.2.2 while循环 2.3 continue与break语句2.4 文件操作函数 三、函数3.1 定义函数3.2 作用域3.3 闭包3.4 函数装饰器3.5 内建函数 一、操作符…...

kubernetes中最小组件——Pod

目录 一、Pod简介 二、Pod的使用方式 三、Pause——Pod中底层基础容器 四、为什么kubernetes这样设计Pod 五、Pod的分类 1.自主式Pod 2.控制器管理的Pod 3.静态Pod 六、Pod容器的分类 1. 基础容器&#xff08;infrastructure container&#xff09; 2. 初始化容器&am…...

C++ 友元

文章目录 前言一、什么是友元二、友元的特性三、示例代码总结 前言 在C编程中&#xff0c;友元&#xff08;friend&#xff09;是一种特殊的关系&#xff0c;允许一个类或函数访问另一个类中的私有成员。 一、什么是友元 1.友元 的定义&#xff1a; 友元在C中可以被用于类和…...

Vulkan 绘制显示设计

背景 众所周知&#xff0c;Vulkan是个跨平台的图形渲染API&#xff0c;为了友好地支持跨平台&#xff0c;Vulkan自然也抽象出了很多接口层去对接各个操作系统&#xff0c;抹平系统间的差异&#xff0c;Swap Chains即为WSI。 其本质上是一种图像队列&#xff0c;此队列会按顺序…...

Linux性能分析工具介绍(一)--cpu及功耗相关工具介绍

目录 一、引言 二、CPU及功耗分析工具介绍 ------>2.1、cpuinfo ------------>2.1.1、cpuid指令 ------>2.2、lscpu ------>2.3、turbostat ------>2.4、rdmsr ------>2.5、mpstat ------>2.6、/proc/stat ------>2.7、powertop ----------…...

智能财务分析的无冕之王-奥威BI数据可视化工具

利用智能数据可视化分析工具&#xff0c;可极大提升财务分析效率和报表可读性&#xff0c;缩短从分析到决策的耗时。但财务分析的难度往往比其他分析更高&#xff0c;因为它的分析指标计算组合变化太多也太快。哪些数据可视化工具能胜任智能财务数据分析&#xff1f; 奥威BI数…...

.NET 应用程序 部署

**硬件支持型号 点击 查看 硬件支持 详情** DTU701 产品详情 DTU702 产品详情 DTU801 产品详情 DTU802 产品详情 DTU902 产品详情 G5501 产品详情 本文内容 在设备上部署 dotnet应用&#xff0c;与任何其他平台的部署相同&#xff0c;可以2种方式&#xff1a; 依赖于框…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...