大数据——HBase原理
摘要
HBase 是一个开源的、非关系型的分布式数据库系统,主要用于存储海量的结构化和半结构化数据。它是基于谷歌的 Bigtable 论文实现的,运行在 Hadoop 分布式文件系统(HDFS)之上,并且可以与 Hadoop 生态系统的其他组件无缝集成。
HBase 的设计目标是提供高可扩展性、实时读写和随机访问能力,这使其特别适合于需要快速处理和查询大数据集的应用场景。它采用行键(Row Key)作为主键,并使用列族(Column Family)来组织数据,数据在物理上按照行键的顺序存储,支持范围查询。
HBase 提供了强大的数据模型,支持版本控制和稀疏存储,同时还支持通过 MapReduce 进行批处理操作。它具有自动分片、负载均衡和故障恢复能力,确保了系统的高可用性和可靠性。HBase 常用于需要高吞吐量和低延迟的应用,如实时分析、日志处理和用户行为跟踪等。
HBase 的查询语言类似于 SQL,但更适合大规模分布式数据存储和处理。它与传统的关系数据库不同,不支持复杂的关系操作,如 JOIN 和事务处理,但通过灵活的设计和高效的存储模型,HBase 在大数据场景下表现出色。
1. HBase基础概念
HBase是一种分布式、可扩展、支持海量数据存储的 NoSQL 数据库。 逻辑上,HBase的数据模型同关系型数据库很类似,数据存储在一张表中,有行有列。但从HBase的底层物理存储结构(K-V)来看,HBase更像是一个multi-dimensional map。
HBase被称为内存数据库,主要是因为它的数据存储和读取主要依赖于内存,这使得HBase能够提供高性能的随机读写能力。 具体来说,HBase具备以下几个核心特性:
- HBase使用内存作为主要的数据缓存,大部分常用数据都被存储在内存中,这样可以大幅度提高数据读取的速度;
- HBase支持数据的实时随机访问,这是因为HBase的数据模型是基于列的,列数据存储在一起,可以快速定位到具体的数据;
- HBase设计了高效的写入策略,通过Write-Ahead Log (WAL)机制,数据首先被写入到内存中,然后再同步到硬盘,这样可以大幅度提高写入的效率。
2. HBase系统架构
Region Server:Region Server为 Region的管理者,其实现类为HRegionServer,主要作用如下:
- 对于数据的操作:get, put, delete;
- 对于Region的操作:splitRegion、compactRegion。
Master:Master是所有Region Server的管理者,其实现类为HMaster,主要作用如下:
- 对于表的操作:create, delete, alter
- 对于RegionServer的操作:分配regions到每个RegionServer,监控每个RegionServer的状态,负载均衡和故障转移。
Zookeeper:HBase通过Zookeeper来做Master的高可用、RegionServer的监控、元数据的入口以及集群配置的维护等工作。
HDFS:HDFS为HBase提供最终的底层数据存储服务,同时为HBase提供高可用的支持。
StoreFile:保存实际数据的物理文件,StoreFile以HFile的形式存储在HDFS上。每个Store会有一个或多个StoreFile(HFile),数据在每个StoreFile中都是有序的。
MemStore:写缓存,由于HFile中的数据要求是有序的,所以数据是先存储在MemStore中,排好序后,等到达刷写时机才会刷写到HFile,每次刷写都会形成一个新的HFile。
WAL:由于数据要经MemStore排序后才能刷写到HFile,但把数据保存在内存中会有很高的概率导致数据丢失,为了解决这个问题,数据会先写在一个叫做Write-Ahead logfile的文件中,然后再写入MemStore中。所以在系统出现故障的时候,数据可以通过这个日志文件重建。
3. HBase数据模型
3.1. HBase逻辑结构
3.2. HBase物理结构
- Name Space:命名空间,类似于关系型数据库的DatabBase概念沐,与mysql的数据库的概念类似,每个命名空间下有多个表。HBase有两个自带的命名空间,分别是hbase和default,hbase中存放的是HBase内置的表,default表是用户默认使用的命名空间。
- Region:类似于关系型数据库的表概念。不同的是,HBase定义表时只需要声明列族即可,不需要声明具体的列。这意味着,往HBase写入数据时,字段可以动态、按需指定。因此和关系型数据库相比,HBase能够轻松应对字段变更的场景。
- Row:HBase表中的每行数据都由一个RowKey和多个Column(列)组成,数据是按照RowKey的字典顺序存储的,并且查询数据时只能根据RowKey进行检索,所以RowKey的设计十分重要。
- Column:HBase中的每个列都由Column Family(列族)和Column Qualifier(列限定符)进行限定,例如info:name,info:age。建表时,只需指明列族,而列限定符无需预先定义。
- Time Stamp:用于标识数据的不同版本(version),每条数据写入时,如果不指定时间戳,系统会自动为其加上该字段,其值为写入HBase的时间。
- Cell:由{rowkey, column Family:column Qualifier, time Stamp} 唯一确定的单元。cell中的数据是没有类型的,全部是字节码形式存贮。
4. HBase的函数API
4.1. HBase基本函数
# 进入HBase客户端命令行
bin/hbase shell# 查看当前数据库中有哪些表
hbase(main):002:0> list# 创建表
hbase(main):002:0> create 'student','info'# 插入数据
hbase(main):003:0> put 'student','1001','info:sex','male'
hbase(main):004:0> put 'student','1001','info:age','18'# 扫描查看表数据
hbase(main):008:0> scan 'student'
hbase(main):009:0> scan 'student',{STARTROW => '1001', STOPROW => '1001'}
hbase(main):010:0> scan 'student',{STARTROW => '1001'}# 查看表结构
hbase(main):011:0> describe ‘student’# 更新指定字段的数据
hbase(main):012:0> put 'student','1001','info:name','Nick'
hbase(main):013:0> put 'student','1001','info:age','100'# 查看“指定行”或“指定列族:列”的数据
hbase(main):014:0> get 'student','1001'
hbase(main):015:0> get 'student','1001','info:name'# 统计表数据行数
hbase(main):021:0> count 'student'# 删除某rowkey的全部数据:
hbase(main):016:0> deleteall 'student','1001'# 删除某rowkey的某一列数据:
hbase(main):017:0> delete 'student','1002','info:sex'# 清空表数据 清空表student表
hbase(main):018:0> truncate 'student'# 删除表,首先需要先让该表为disable状态:
hbase(main):019:0> disable 'student'# 然后才能drop这个表:
hbase(main):020:0> drop 'student'如果直接drop表,会报错:ERROR: Table student is enabled. Disable it first.变更表信息,将info列族中的数据存放3个版本:
hbase(main):022:0> alter 'student',{NAME=>'info',VERSIONS=>3}
hbase(main):022:0> get 'student','1001',{COLUMN=>'info:name',VERSIONS=>3}
4.2. HBase基本API
DDL语句(表级别操作):
- 判断表是否存在
- 创建表
- 创建命名空间
- 删除表
DML语句(数据级别操作):
- 插入数据
- 查询数据
- 修改数据
- 删除数据
表的操作对象是HBaseAdmin admin
public static Configuration conf;
static{//使用HBaseConfiguration的单例方法实例化conf = HBaseConfiguration.create();conf.set("hbase.zookeeper.quorum", "192.166.9.102");conf.set("hbase.zookeeper.property.clientPort", "2181");
}
public static boolean isTableExist(String tableName) throws MasterNotRunningException,ZooKeeperConnectionException, IOException{//在HBase中管理、访问表需要先创建HBaseAdmin对象//Connection connection = ConnectionFactory.createConnection(conf);//HBaseAdmin admin = (HBaseAdmin) connection.getAdmin();HBaseAdmin admin = new HBaseAdmin(conf);return admin.tableExists(tableName);
}
public static void createTable(String tableName, String... columnFamily) throwsMasterNotRunningException, ZooKeeperConnectionException, IOException{HBaseAdmin admin = new HBaseAdmin(conf);//判断表是否存在if(isTableExist(tableName)){System.out.println("表" + tableName + "已存在");//System.exit(0);}else{//创建表属性对象,表名需要转字节HTableDescriptor descriptor = new HTableDescriptor(TableName.valueOf(tableName));//创建多个列族for(String cf : columnFamily){descriptor.addFamily(new HColumnDescriptor(cf));}//根据对表的配置,创建表admin.createTable(descriptor);System.out.println("表" + tableName + "创建成功!");}
}
public static void dropTable(String tableName) throws MasterNotRunningException,ZooKeeperConnectionException, IOException{HBaseAdmin admin = new HBaseAdmin(conf);if(isTableExist(tableName)){# 先disbale 在能实现删除表admin.disableTable(tableName);admin.deleteTable(tableName);System.out.println("表" + tableName + "删除成功!");}else{System.out.println("表" + tableName + "不存在!");}
}
数据操作对象是 HTable hTable
public static void addRowData(String tableName, String rowKey, String columnFamily, Stringcolumn, String value) throws IOException{//创建HTable对象 就是操作的对象HTable hTable = new HTable(conf, tableName);//向表中插入数据Put put = new Put(Bytes.toBytes(rowKey));//向Put对象中组装数据put.add(Bytes.toBytes(columnFamily), Bytes.toBytes(column), Bytes.toBytes(value));hTable.put(put);hTable.close();System.out.println("插入数据成功");
}
public static void deleteMultiRow(String tableName, String... rows) throws IOException{HTable hTable = new HTable(conf, tableName);List<Delete> deleteList = new ArrayList<Delete>();for(String row : rows){Delete delete = new Delete(Bytes.toBytes(row));deleteList.add(delete);}hTable.delete(deleteList);hTable.close();
}
public static void getAllRows(String tableName) throws IOException{HTable hTable = new HTable(conf, tableName);//得到用于扫描region的对象Scan scan = new Scan();//使用HTable得到resultcanner实现类的对象ResultScanner resultScanner = hTable.getScanner(scan);for(Result result : resultScanner){Cell[] cells = result.rawCells();for(Cell cell : cells){//得到rowkeySystem.out.println("行键:" + Bytes.toString(CellUtil.cloneRow(cell)));//得到列族System.out.println("列族" + Bytes.toString(CellUtil.cloneFamily(cell)));System.out.println("列:" + Bytes.toString(CellUtil.cloneQualifier(cell)));System.out.println("值:" + Bytes.toString(CellUtil.cloneValue(cell)));}}
public static void getRow(String tableName, String rowKey) throws IOException{HTable table = new HTable(conf, tableName);Get get = new Get(Bytes.toBytes(rowKey));//get.setMaxVersions();显示所有版本//get.setTimeStamp();显示指定时间戳的版本Result result = table.get(get);for(Cell cell : result.rawCells()){System.out.println("行键:" + Bytes.toString(result.getRow()));System.out.println("列族" + Bytes.toString(CellUtil.cloneFamily(cell)));System.out.println("列:" + Bytes.toString(CellUtil.cloneQualifier(cell)));System.out.println("值:" + Bytes.toString(CellUtil.cloneValue(cell)));System.out.println("时间戳:" + cell.getTimestamp());}
}
public static void getRowQualifier(String tableName, String rowKey, String family, Stringqualifier) throws IOException{HTable table = new HTable(conf, tableName);Get get = new Get(Bytes.toBytes(rowKey));get.addColumn(Bytes.toBytes(family), Bytes.toBytes(qualifier));Result result = table.get(get);for(Cell cell : result.rawCells()){System.out.println("行键:" + Bytes.toString(result.getRow()));System.out.println("列族" + Bytes.toString(CellUtil.cloneFamily(cell)));System.out.println("列:" + Bytes.toString(CellUtil.cloneQualifier(cell)));System.out.println("值:" + Bytes.toString(CellUtil.cloneValue(cell)));}
}
5. HBase的写流程(与Rocketmq写类似)
写流程:
- Client先访问zookeeper,获取hbase:meta表位于哪个Region Server。
- 访问对应的Region Server,获取hbase:meta表,根据读请求的namespace:table/rowkey,查询出目标数据位于哪个Region Server中的哪个Region中。并将该table的region信息以及meta表的位置信息缓存在客户端的meta cache,方便下次访问。
- 与目标Region Server进行通讯;
- 将数据顺序写入(追加)到WAL;
- 将数据写入对应的MemStore,数据会在MemStore进行排序;
- 向客户端发送ack;
- 等达到MemStore的刷写时机后,将数据刷写到HFile。
6. HBase的读流程(读比写慢数据库)
HBase的读写流程是先把磁盘和内存的数据一起读区出来,然后在进行的merge。
读流程
- Client先访问zookeeper,获取hbase:meta表位于哪个Region Server。
- 访问对应的Region Server,获取hbase:meta表,根据读请求的namespace:table/rowkey,查询出目标数据位于哪个Region Server中的哪个Region中。并将该table的region信息以及meta表的位置信息缓存在客户端的meta cache,方便下次访问。
- 与目标Region Server进行通讯;
- 分别在Block Cache(读缓存),MemStore和Store File(HFile)中查询目标数据,并将查到的所有数据进行合并。此处所有数据是指同一条数据的不同版本(time stamp)或者不同的类型(Put/Delete)。
- 将从文件中查询到的数据块(Block,HFile数据存储单元,默认大小为64KB)缓存到Block Cache。
- 将合并后的最终结果返回给客户端。
7. HBase的Flush流程(数据刷盘机制,与mysql的数据刷盘类似)
MemStore刷写时机:
- 当某个memstroe的大小达到了hbase.hregion.memstore.flush.size(默认值128M),其所在region的所有memstore都会刷写。当memstore的大小达到了 hbase.hregion.memstore.flush.size(默认值128M),*hbase.hregion.memstore.block.multiplier(默认值4)时,会阻止继续往该memstore写数据。
- 当region server中memstore的总大小达到 java_heapsize,*hbase.regionserver.global.memstore.size(默认值0.4)*hbase.regionserver.global.memstore.size.lower.limit(默认值0.95),
- region会按照其所有memstore的大小顺序(由大到小)依次进行刷写。直到region server中所有memstore的总大小减小到上述值以下。
- 当region server中memstore的总大小达到 java_heapsize ,*hbase.regionserver.global.memstore.size(默认值0.4)时,会阻止继续往所有的memstore写数据。
- 到达自动刷写的时间,也会触发memstore flush。自动刷新的时间间隔由该属性进行配置hbase.regionserver.optionalcacheflushinterval(默认1小时)。
- 当WAL文件的数量超过hbase.regionserver.max.logs,region会按照时间顺序依次进行刷写,直到WAL文件数量减小到hbase.regionserver.max.log以下(该属性名已经废弃,现无需手动设置,最大值为32)。
8. HBase的StoreFile Compact流程(小文件合并)
由于memstore每次刷写都会生成一个新的HFile,且同一个字段的不同版本(timestamp)和不同类型(Put/Delete)有可能会分布在不同的HFile中,因此查询时需要遍历所有的HFile。为了减少HFile的个数,以及清理掉过期和删除的数据,会进行StoreFile Compaction。
Compaction分为两种,分别是Minor Compaction和Major Compaction。Minor Compaction会将临近的若干个较小的HFile合并成一个较大的HFile,但不会清理过期和删除的数据。Major Compaction会将一个Store下的所有的HFile合并成一个大HFile,并且会清理掉过期和删除的数据。
9. HBase的Region切分流程(大文件拆分)
默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的Region Server,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的Region Server。
Region Split时机:
- 当1个region中的某个Store下所有StoreFile的总大小超过hbase.hregion.max.filesize,该Region就会进行拆分(0.94版本之前)。
- 当1个region中的某个Store下所有StoreFile的总大小超过Min(R^2 * "hbase.hregion.memstore.flush.size",hbase.hregion.max.filesize"),该Region就会进行拆分,其中R为当前Region Server中属于该Table的个数(0.94版本之后)
10. HBase的数据删除流程
- 逻辑删除: HBase不会立即在物理存储上删除数据,而是采用逻辑删除的方式。当执行删除操作时,HBase会将一条特殊的删除标记(Tombstone)插入到相应的数据单元中。这个删除标记指示这个数据单元已被删除,并且会在数据保留的时间后清理掉。
- Major Compaction(主要合并): HBase定期执行Major Compaction操作,它会合并和清理数据文件,删除标记和过期数据。Major Compaction将不再需要的数据清理掉,从而释放磁盘空间,并提高读取性能。
- Minor Compaction(次要合并): 在Major Compaction之外,HBase还执行Minor Compaction,它用于合并较小的数据文件以优化存储布局,但不会清理删除标记。
- 删除标记的清理: 当Major Compaction执行时,HBase会检查数据单元中的删除标记,如果数据的所有版本都已被标记为删除,则在Major Compaction中清理掉这些数据。
需要注意的是,HBase的删除操作并不是实时的,而是通过Compaction过程逐步进行的。这意味着一条数据的删除标记可能会在Compaction之前存在一段时间,直到Compaction执行并将其清理。这种机制有助于保持HBase的高性能和高吞吐量,同时确保数据的持久性和一致性。总之,HBase通过逻辑删除和Compaction机制来处理数据的删除操作。删除数据会在逻辑上插入删除标记,而实际的物理清理会在Compaction过程中进行。这种机制可以平衡数据的删除和性能需求,确保数据的有效管理和存储。
11. HBase的优化设计
11.1. HBase的Master的高可用设计
在HBase中HMaster负责监控HRegionServer的生命周期,均衡RegionServer的负载,如果HMaster挂掉了,那么整个HBase集群将陷入不健康的状态,并且此时的工作状态并不会维持太久。所以HBase支持对HMaster的高可用配置。
关闭HBase集群(如果没有开启则跳过此步)
[xjl@hadoop102 hbase]$ bin/stop-hbase.sh在conf目录下创建backup-masters文件
[xjl@hadoop102 hbase]$ touch conf/backup-masters在backup-masters文件中配置高可用HMaster节点
[xjl@hadoop102 hbase]$ echo hadoop103 > conf/backup-masters将整个conf目录scp到其他节点
[xjl@hadoop102 hbase]$ scp -r conf/ hadoop103:/opt/module/hbase/
[xjl@hadoop102 hbase]$ scp -r conf/ hadoop104:/opt/module/hbase/打开页面测试查看
11.2. HBase的预分区设计
每一个region维护着StartRow与EndRow,如果加入的数据符合某个Region维护的RowKey范围,则该数据交给这个Region维护。那么依照这个原则,我们可以将数据所要投放的分区提前大致的规划好,以提高HBase性能。
# 手动设定预分区
Hbase> create 'staff1','info','partition1',SPLITS => ['1000','2000','3000','4000']# 生成16进制序列预分区
create 'staff2','info','partition2',{NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}# 按照文件中设置的规则预分区
创建splits.txt文件内容如下:
aaaa
bbbb
cccc
dddd
然后执行:
create 'staff3','partition3',SPLITS_FILE => 'splits.txt'# 使用JavaAPI创建预分区//自定义算法,产生一系列hash散列值存储在二维数组中byte[][] splitKeys = 某个散列值函数//创建HbaseAdmin实例HBaseAdmin hAdmin = new HBaseAdmin(HbaseConfiguration.create());//创建HTableDescriptor实例HTableDescriptor tableDesc = new HTableDescriptor(tableName);//通过HTableDescriptor实例和散列值二维数组创建带有预分区的Hbase表hAdmin.createTable(tableDesc, splitKeys);
11.3. HBase的RowKey设计(随机性,防止数据倾斜)
一条数据的唯一标识就是RowKey,那么这条数据存储于哪个分区,取决于RowKey处于哪个一个预分区的区间内,设计RowKey的主要目的,就是让数据均匀的分布于所有的region中,在一定程度上防止数据倾斜。接下来我们就谈一谈RowKey常用的设计方案。
# 生成随机数、hash、散列值
比如:
原本rowKey为1001的,SHA1后变成:dd01903921ea24941c26a48f2cec24e0bb0e8cc7
原本rowKey为3001的,SHA1后变成:49042c54de64a1e9bf0b33e00245660ef92dc7bd
原本rowKey为5001的,SHA1后变成:7b61dec07e02c188790670af43e717f0f46e8913
在做此操作之前,一般我们会选择从数据集中抽取样本,来决定什么样的rowKey来Hash后作为每个分区的临界值。# 字符串反转
20170524000001转成10000042507102
20170524000002转成20000042507102
这样也可以在一定程度上散列逐步put进来的数据。# 字符串拼接
20170524000001_a12e
20170524000001_93i7
11.4. HBase的内存优化
HBase操作过程中需要大量的内存开销,毕竟Table是可以缓存在内存中的,一般会分配整个可用内存的70%给HBase的Java堆。但是不建议分配非常大的堆内存,因为GC过程持续太久会导致RegionServer处于长期不可用状态,一般16~48G内存就可以了,如果因为框架占用内存过高导致系统内存不足,框架一样会被系统服务拖死。
11.5. HBase基础优化
1.允许在HDFS的文件中追加内容
hdfs-site.xml、hbase-site.xml
属性:dfs.support.append
解释:开启HDFS追加同步,可以优秀的配合HBase的数据同步和持久化。默认值为true。2.优化DataNode允许的最大文件打开数
hdfs-site.xml
属性:dfs.datanode.max.transfer.threads
解释:HBase一般都会同一时间操作大量的文件,根据集群的数量和规模以及数据动作,设置为4096或者更高。默认值:40963.优化延迟高的数据操作的等待时间
hdfs-site.xml
属性:dfs.image.transfer.timeout
解释:如果对于某一次数据操作来讲,延迟非常高,socket需要等待更长的时间,建议把该值设置为更大的值(默认60000毫秒),以确保socket不会被timeout掉。4.优化数据的写入效率
mapred-site.xml
属性:
mapreduce.map.output.compress
mapreduce.map.output.compress.codec
解释:开启这两个数据可以大大提高文件的写入效率,减少写入时间。第一个属性值修改为true,第二个属性值修改为:org.apache.hadoop.io.compress.GzipCodec或者其他压缩方式。5.设置RPC监听数量
hbase-site.xml
属性:Hbase.regionserver.handler.count
解释:默认值为30,用于指定RPC监听的数量,可以根据客户端的请求数进行调整,读写请求较多时,增加此值。6.优化HStore文件大小
hbase-site.xml
属性:hbase.hregion.max.filesize
解释:默认值10737418240(10GB),如果需要运行HBase的MR任务,可以减小此值,因为一个region对应一个map任务,如果单个region过大,会导致map任务执行时间过长。该值的意思就是,如果HFile的大小达到这个数值,则这个region会被切分为两个Hfile。7.优化HBase客户端缓存
hbase-site.xml
属性:hbase.client.write.buffer
解释:用于指定Hbase客户端缓存,增大该值可以减少RPC调用次数,但是会消耗更多内存,反之则反之。一般我们需要设定一定的缓存大小,以达到减少RPC次数的目的。8.指定scan.next扫描HBase所获取的行数
hbase-site.xml
属性:hbase.client.scanner.caching
解释:用于指定scan.next方法获取的默认行数,值越大,消耗内存越大。9.flush、compact、split机制
当MemStore达到阈值,将Memstore中的数据Flush进Storefile;compact机制则是把flush出来的小文件合并成大的Storefile文件。split则是当Region达到阈值,会把过大的Region一分为二。
涉及属性:
即:128M就是Memstore的默认阈值
hbase.hregion.memstore.flush.size:134217728
即:这个参数的作用是当单个HRegion内所有的Memstore大小总和超过指定值时,flush该HRegion的所有memstore。RegionServer的flush是通过将请求添加一个队列,模拟生产消费模型来异步处理的。那这里就有一个问题,当队列来不及消费,产生大量积压请求时,可能会导致内存陡增,最坏的情况是触发OOM。
hbase.regionserver.global.memstore.upperLimit:0.4
hbase.regionserver.global.memstore.lowerLimit:0.38
即:当MemStore使用内存总量达到hbase.regionserver.global.memstore.upperLimit指定值时,将会有多个MemStores flush到文件中,MemStore flush 顺序是按照大小降序执行的,直到刷新到MemStore使用内存略小于lowerLimit
博文参考
https://www.cnblogs.com/datadance/p/16327298.html
https://www.cnblogs.com/datadance/p/16327298.html
相关文章:

大数据——HBase原理
摘要 HBase 是一个开源的、非关系型的分布式数据库系统,主要用于存储海量的结构化和半结构化数据。它是基于谷歌的 Bigtable 论文实现的,运行在 Hadoop 分布式文件系统(HDFS)之上,并且可以与 Hadoop 生态系统的其他组…...

《电视技术》是什么级别的期刊?是正规期刊吗?能评职称吗?
问题解答 问:《电视技术》是不是核心期刊? 答:不是,是知网收录的第一批认定学术期刊。 问:《电视技术》级别? 答:国家级。主管单位:中国电子科技集团公司 主办单位ÿ…...
网络编程 --------- 2、socket网络编程接口
1、什么是socket 套接字 socke套接字是一个编程的接口 (网络编程的接口)、是一种特殊的文件描述符 (read/write),不局限于TCP/IP 。socket是独立于具体协议的网络编程接口这个接口是位于 应用层和传输层之间 。 类型: (1)流式套接字 SOCK_ST…...
C# Deconstruct详解
总目录 前言 该文来源于探索弃元的使用,由弃元了解到元组,由元组又了解到解构方法Deconstruct。 另外本文中 解构和析构一个意思,不要在意! 一、Deconstruct是什么? 1. 关于元组 如果我们想了解Deconstruct 的使用&…...
Java 面试常见问题之——为什么重写equals时必须重写hashCode方法
Java 面试常见问题之——为什么重写equals时必须重写hashCode方法 当重写 equals 方法时,通常也应该重写 hashCode 方法,原因主要有以下几点: 一致性原则:根据 Java 的约定,如果两个对象通过 equals 方法比较返回 tr…...
后端给的树形结构 递归 改造成阶联选择器所需要的lable、value结构
赋值:this.newTreeData this.renameFields(this.treeData) 递归方法:renameFields (tree) {return tree.map(node > {// 创建一个新对象来存放修改后的字段名const newNode {value: node.id,label: node.title,// 如果有子节点,则递归处理…...

文献阅读:基于拓扑结构模型构建ICI收益诊断模型
介绍 Custom scoring based on ecological topology of gut microbiota associated with cancer immunotherapy outcome是来自法国Gustave Roussy Cancer Campus的Laurence Zitvogel实验室最近发表在cell的关于使用肠道微生物拓扑结构预测免疫治疗疗效的文章。 该研究提供基于…...

Python文献调研(四)QtDesigner的布局
一、新建项目: 1.打开pycharm,新建一个Python项目 (1)右键项目列表区,找到我们之前配置好的外部工具,点击Pyside6 QtDesigner 打开Qt Designer后会是这个界面: (2)此时…...

CentOS Linux release 7.9.2009 中sudo命令未找到
先在 Windows 环境中下载 sudo 的安装包 下载安装包:https://www.sudo.ws/releases/stable/ 然后把安装包拷贝的 Centos 中,cd 进入安装包所在的目录执行下面的命令: 格式:rpm -Uhv xxxxx.rpm rpm -Uhv sudo-logsrvd-1.9.15-6.…...

生产计划问题的不同最优化工具软件求解
一、优化求解软件简介 众所周知,常用的优化工具软件有Lingo、Mathcad和MATLAB。 1. LINGO是Linear Interactive and General Optimizer的缩写,即“交互式的线性和通用优化求解器”,由美国LINDO系统公司(Lindo System Inc.&…...

Java关键字及保留字总结
文章目录 Java关键字及保留字总结(按首字母字母顺序所排列)1.abstract2.boolean3.break4.byte5.case6.catch7.char8.class9.continue10.default11.do12.double13.else14.enum15.extends16.final17.finally18.float19.for20.if21.implements22.import23.i…...

【PGCCC】PostgreSQL 14 小版本分析,有那个版本不建议使用#PG中级
以下是对 PostgreSQL 14 各个小版本的详细分析,包括每个版本的主要变化、修复的 bug 和潜在的问题: PostgreSQL 14.0 发布日期:2021 年 9 月 30 日 主要变化: 增加了并行查询的改进,提升了性能。增强了 JSON 数据类…...
B树在数据库中的应用:理论与实践
B树在数据库中的应用:理论与实践 B树(B-tree)是一种自平衡的树数据结构,广泛应用于数据库系统中,特别是用于实现索引和文件系统中的关键字查找。B树的设计目标是保持数据有序并允许高效的查找、插入和删除操作。本文将…...
网络编程 -------- 3、TCP_UDP_UNIX
1、基于TCP的套接字编程流程 Server.c socket bind (服务器的ip端口) listen accept recv / send close Client.c socket connect (服务器的ip端口) …...

口袋奇兵:游戏辅助教程!陆军搭配阵容推荐,平民必备!
《口袋奇兵》是一款策略类手游,玩家需要在游戏中组建和指挥自己的军队,进行各种战斗和任务。为了在游戏中取得更好的成绩,合理搭配英雄和使用辅助工具是非常重要的。本攻略将为大家介绍一种强力的陆军搭配阵容,以及如何利用VMOS云…...
Spring Boot 集成参数效验 Validator
为什么需要参数效验? 在业务开发中,为了防止非法参数对业务造成影响,所以需要对用户输入的正确性、数据完整性、安全性、业务规则的执行做效验,靠代码对接口参数做if判断的话就太繁琐了,代码冗余且可读性差(主要是不够优雅)。 Validator效验框架遵循了JSR-303验证规范…...

63、ELK安装和部署
一、ELK日志系统 1.1、ELK平台的定义 ELK平台是一套完整的日志集中处理解决方案,将ElasticSearch、Logstash和Kiabana 三个开源工具配合使用,完成更强大的用户对日志的查询、排序、统计需求 E:elasticsearch ES分布式索引型非关系数据库,存…...

【Dash】简单的直方图
一、Visualizing Data The Plotly graphing library has more than 50 chart types to choose from. In this example, we will make use of the histogram chart. # Import packages from dash import Dash, html, dash_table, dcc import pandas as pd import plotly.expre…...

【CTF-Crypto】格密码基础(例题较多,非常适合入门!)
格密码相关 文章目录 格密码相关格密码基本概念(属于后量子密码)基础的格运算(行列式运算)SVP(shortest Vector Problem)最短向量问题CVP(Closet Vector Problem)最近向量问题 做题要…...

Java对象流
对象流 对象输入流 java.io.ObjectInputStream使用对象流可以进行对象反序列化 构造器 ObjectInputStream(InputStream in) 将当前创建的对象输入流链接在指定的输入流上 方法 Object readObject() 进行对象反序列化并返回。该方法会从当前对象输入流链接的流中读取若干…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...