Google的三篇论文,Google File System ,MapReduce 以及Big Table 可以说是整个大数据领域的三驾马车,这里,我们简单介绍下这三驾马车基本都是干哈的,重点解读下Bigtable: A Distributed Storage System for Structured Data 。
2003年的GFS :GFS是一个可扩展的分布式文件系统,主要解决传统单机文件系统中磁盘小,数据存储无冗余等问题;
2004年的MapReduce :MapReduce是一个基于分布式文件系统(例如,GFS)的分布式计算框架,主要用来处理大规模数据集;
2006年的BigTable :BigTable是一个用来管理结构化数据的分布式存储系统,其本质上一个分布式KV存储系统。
BigTable是个啥?
BigTable是Google内部用来管理结构化数据的分布式存储系统,BigTable可以轻易地扩展到上千台机器,BigTable具有以下优点:
适用场景广泛:从需要高吞吐量的批处理作业到低延迟的用户数据服务,BigTable都可以胜任。
可伸缩:集群规模可水平扩展,BigTable部署规模可以小到3~5台,大到数千台,从而支撑不同的数据量;
高性能:性能这个,想必不用我BB了吧,各位看官,你们怎么看呢?
高可用:BigTable是主从结构,不会产生单点故障;底层是GFS,数据冗余备份;这还不具有高可用嘛???
与关系型数据库不同,BigTable并不支持完整的关系数据模型,也就是说,BigTable是一个NoSQL数据库,BigTable为用户提供了一个简单的数据模型,该模型主要有以下两个特点:
客户端可以对数据的布局和格式动态控制;这点与关系型数据库有很大的差别,关系型数据库中,表创建完成后,表中存储的数据格式基本就固定了,列的数量及格式都无法再改变了,BigTable则不同,BigTable的列可以动态增加,完全由客户端控制。
客户端可以推理底层数据存储系统中表示的数据的局部属性(有点不太理解)。
BigTable中的数据是通过行(row)和列(column)进行索引的,行和列可以是任意字符串。
客户端可以将各种形式的结构化和半结构数据序列化字符串,但BigTable只是将数据(Data)看做是未解释字符串(字节数组)进行处理。
客户端可以通过模式(Schema)参数来控制底层数据存储的位置,BigTable的模式参数允许客户端动态控制是从内存还是磁盘提供数据。
BigTable数据模型
让我们先来看看BigTable 论文中是如何对BigTable
定义的吧~
A BigTable is a Sparse, Distributed, Persistent Multi-Dimensional Sorted Map
. The Map
is indexed by a row key, column key, and a timestamp
; each value in the map is an uninterpreted array of bytes
.
BigTable是一个Map,即Key/Value键值对,这个Map有啥特点呢?稀疏的,分布式的,持久化存储的且多维度排序的。
对于Map数据结构来说,最常用的操作就是通过Key检索Value,BigTable中的Value是通过行,列,时间戳进行索引的。
# BigTable/Map的索引结构
(row:string, column:string, time:int64) ==> string
BigTable-WebPage-Example.png
上图是为Web页面创建的BigTable表Webtable :
row为url地址的逆序;
列族contents用来存储Web页面内容;
列族anchor中存储Web页面中任何引用其他页面的锚点连接;
注意:BigTable中,每个Cell都有多个Version,每个Version对应一个时间戳。
Row Key
BigTable中的row key
可以是任意字符串(大部分场景下,用户使用的row key 大小为10-100字节,但BigTable当前分配大小为64KB)。
客户端每次读取/写入数据时,指定row key
时,无论有多少列同时被读取/写入,该读写操作都是原子操作的。
BigTable底层是按row key
的字典顺序存储的,给定BigTable表,其row key range
是动态分区的,每个分区称为一个Tablet
。
Tips:较小范围的row key
数据读取会更高效,原因在于,这些数据读取时,只需要与很少的机器通信即可,效率较高。
Tips:客户端可以充分利用上述属性,从而加快其数据访问,获取更高的吞吐量。例如,在Webtable 中,使用url的逆序作为row key,这样做的好处是,访问同一网站的页面时,这些页面通常会对应同一台机器,不需要与集群中多个节点通信,读取效率更高。
Column Families
多个Column Key
构成的集合称为列族Column Families
,Column Key
是最基本的访问控制单元。
同一列族中的数据通常具有相同的数据类型(一般情况下,同一列族的数据会放在一起进行压缩存储)。
数据以列族(Column Families**)中某个列(**
Column Key` )进行存储之前,必须先创建该列族才行。
Tips:通常情况下,一张BitTable表的列族得数量可能比较小(最多几百个),而且在使用过程中,列族通常是不变的,相反的,每个表可以拥有无数个列,也就是说,每个列族都可以拥有无数个列,而且列是不需要提前定义的。
Column Key
通常使用语法family:qualifier
进行命名,列族必须由可打印字符构成,而列名可以由任意字符构成。
Timestamps
BigTable表中每个Cell包含同一数据的多个版本,这些版本通过时间戳进行索引,BigTable中的时间戳是64位整数。
时间戳可以由服务端生成,也可以由客户端生成,需要避免冲突的应用程序必须由自身生成相应的时间戳。
不同版本的Cell以时间戳降序的方式进行存储,以至于时间戳最近的版本最先会读取到。
为了避免Cell的数据版本过多,提供列族级别的配置项,以便BigTable自动删除旧的数据版本,一种是只保留最近的几个版本,另一种是只保留足够新的版本数据(例如,保留最近7天写入的数据版本)。
BigTable API
BigTable API提供创建/删除表和列族的方法。
BigTable API提供修改集群,表,列族元数据方法,例如,修改访问控制权限等。
客户端应用程序可以执行写入/删除BigTable中的值,根据row key查询值,迭代表中部分数据集等操作。
// Open the table
Table *t = OpenOrDie("/bigtable/web/wetable");
// Write a new anchor and delete an old anchor
RowMutation r1(T, "com.cnn.www");
r1.Set("anchor:www.c-span.org", "CNN");
r1.Delete("anchor:www.abc.com");
Operation op;
// 应用原子操作到Webtable中的r1上
Apply(&op, &r1);
客户端可以在多个列族上进行迭代操作,同时,BigTable提供了几种row, columns, timestamps构建方法来生成Scan实例。
Scanner scanner(T);
ScanStream *stream;
stream = scanner.FetchColumnFamily("anchor");
stream->SetReturnAllVersions();
scanner.Lookup("com.cnn.www");
for (; !stream->Done(); stream->Next()) {
printf("%s %s %lld %s\n",
scanner.RowName(),
stream->ColumnName(),
stream->MicroTimestamp(),
stream->Value());
}
另外,BigTable支持其他更复杂地操作数据的方式:
支持单行(single-row)事务,可以实现给定row key
时执行原子性的读-改-写 操作。
BigTable提供了批量接口,但不支持多行的事务操作。
BigTable允许将Cell用作整数计数器。
BigTable支持在服务端地址空间内执行客户端脚本,该脚本为Sawzall
语言(懵逼)。
BigTable构建基础
BigTable是基于Google的一些基础组件构建而成的。
BigTable使用GFS(Google File System)来存储日志(log)和数据(data)文件。
BigTable集群通常运行在一个共享的服务器集群中,BigTable的进程通常与其他分布式应用程序进程共享同一台服务器。
BigTable依赖集群管理系统来实现作业调度,管理共享机器上的资源,处理机器故障以及监视机器状态。
BigTable使用Google SSTable
文件格式来存储内部数据,SSTable
提供了从keys
到values
的持久化的,顺序的,不可变的映射,另外,SSTable
中keys和values均是任意字节数组,另外,SSTable
提供了根据key检索value以及根据key范围检索Value的功能。
SSTable
由很多Block
(每个Block默认大小为64KB,可配置的)组成,Block Index
(存储在Block尾部)用来定位Blocks,当客户端打开SSTable
时,会将Block Index
加载到内存的。
从SSTable
中检索指定key
的values
时可以通过Single Disk Seek
实现:
首先加载Block Index
到内存中,然后通过二分检索到key
所在的Block,最后将磁盘中合适的Block
加载到内存检索即可。
BigTable依赖高可用且可持久化的分布式锁服务Chubby,Chubby服务包含4个活跃的副本(节点),其中一个节点选举为Master并处理用户请求,当大多数副本副本正常运行且可以互相通信时,Chubby被认为是正常运行的。Chubby使用Paxos算法实现副本数据一致。
Chubby提供了包含目录和小文件的命名空间,每个目录或文件可以当成一个锁来使用,读取和写入文件时原子操作。
Chubby客户端会同步缓存Chubby文件,每个Chubby客户端会自动维护一个与Chubby服务的会话,在会话到期时,如果客户端无法通过Chubby服务更新到期时间,则会话会被中断,会话到期时,客户端会丢失所有所有锁且无法执行open操作。
Chubby客户端可以在Chubby文件/目录上注册回调方法,当会话到期或文件/目录改变是回调该方法。
BigTable使用Chubby完成各种各样的任务:
保证集群内同时最多存在一个Master节点。
存储BigTable表数据的启动位置。
发现Tablet服务以及检测Tablet是否存活。
存储BigTable表Schema信息(每张表的列族信息)。
存储访问控制列表。
BigTable实现原理
BigTable实现主要包括三部分:
客户端需要使用的库
一个Master Server
分配Tablet到哪个Tablet Server上;
检测是否有Tablet Server新增或到期;
Tablet Server负载均衡;
GFS上垃圾文件回收;
处理BigTable表Schema修改(例如,创建/新增表列族);
多个Tablet Server:
每个Tablet Server维护一个Tablet集合(每个Tablet Server通常可以维护10到1000个Tablet);
处理其负责的Tablet的读写请求,在Tablet太大时,负责Tablet的分裂;
根据集群负载情况,Tablet Server可以动态添加或移除。
Tips:与其他单Master分布式存储系统类似,客户端数据不会路由到Master,而是直接与Tablet Server通信,进而实现数据的读写。
Tips:很多BigTable客户端不需要依赖于Master定位Tablet信息,也就是说,大部分场景下客户端不需要与Master通信。
Tablet定位模型
BigTable使用类似B+树的三层结构来存储Tablet位置信息。
BigTable-Tablet-Location.png
第一层:一个Chubby文件,该文件存储了root tablet 的位置信息,由于该文件是Chubby文件,也就意味着,一旦Chubby服务不可用,整个BigTable就丢失了root tablet 的位置,整个服务也就不可用了。
第二层:root tablet ,root tablet 其实就是元数据表METADATA Table
的第一个Tablet,该Tablet中保存着元数据表其他Tablet的位置信息,root tablet 很特殊,为了保证整个树的深度不变,root tablet 从不分裂。
注意:对于元数据表METADATA Table
来说,除了第一个特殊的Tablet来说,其余每个Tablet包含一组用户Tablet位置信息集合。
注意:METADATA Table
存储Tablet位置信息时,Row Key
是通过对Tablet Table Identifier
和该Tablet的End Row
生成的。
注意:每个METADATA Table
的Row Key
大约占用1KB的内存,一般情况下,配置METADATA Table
的大小限制为128MB,也就是说,三层的定位模式大约可以寻址2^34个Tablets。
第三层:其他元数据表的Tablet,这些Tablet与root tablet 共同构成整个元数据表。注意:元数据表虽然特殊,但仍然服从前面介绍的数据模型,每个Tablet也由专门的Tablet Server负责,这就是为什么不需要Master Server提供位置信息的原因,客户端会缓存Tablet的位置信息,如果在缓存中找不到指定Tablet的位置信息,则需要查询该三层结构了,一次访问Chubby服务,两次Tablet Server访问。
Tablet分配模型
每个Tablet只能分配给某个Tablet Server。
Master Server维护当前哪些Tablet Server是活跃的,哪些Tablet分配给了哪些Tablet Server,哪些Tablet还未分配,当某个Tablet还未被分配、且刚好存在Tablet Server有足够的空间装载该Tablet时,Master Server会向该Tablet Server发送装载请求。
BigTable使用Chubby服务来检测Tablet Server是否存活,当Tablet Server启动时,会在特定的Chubby目录下创建排它锁,BigTable会监控该目录来发现哪些Tablet Server存活,当Tablet Server丢失其排它锁时(例如,网络原因导致Tablet Server丢失Chubby会话)。
Chubby服务提供了非常高效地检测会话是否持有锁的机制,且不会导致网络拥塞。
当Tablet Server的排它锁文件存在时,Tablet Server可能会重新获取该锁,也就是,该锁是可重入的;排它锁文件不存在,则Tablet Server不会再次请求该锁,而是自杀。
Tablet Server进程终止是,会尝试释放锁,以便Master Server可以尽快地将其维护的Tablet分配到其他节点上。
Master负责检测Tablet Server是否还在为其他Tablet提供服务,并尽快重新分配其负责的Tablet到其他Tablet Server上。
问题是,Master是如何检测的呢?
Master会定期向每个Tablet Server询问其锁的状态,如果Tablet Server向其报告锁已丢失,或者Master最后几次尝试都无法访问服务器,则Master将尝试获取该Tablet Server对应的排他锁文件,如果可以获取,则说明Chubby处于活跃状态,而Tablet Server已死或者无法访问Chubby,Master可以通过删除其服务器文件来确保Tablet Server不再提供服务。一旦Tablet Server对应的排它锁文件被删除后,Master Server可以将先前分配给该Tablet SErver的所有Tablet移动到其他未分配的Tablet Server中。
为了确保Bigtablet集群不受Master Server与Chubby服务之间网络问题影响,如果Master的Chubbby会话到期,则Master会自动杀死自己,如上所述,Master Server设备故障不会更改Tablet分配到其他Tablet Server上。
当Master Server启动时,在其可以修改Tablet分配之前,需要先感知到当前Tablet分布才行,启动流程如下:
获取Chubby文件(排它锁),阻止并发实例化Master
Master会扫描Tablet Server排它锁的Chubby文件目录,拿到当前活跃Tablet Server信息
Master与所有Tablet Server通信获取其所维护的Tablet信息
Master会同时扫描METADATA
表获取Tablets集合,在扫描的过程中,当Master发现了还未分配的Tablet时,Master将该Tablet加入未分配的Tablet集合等待合适的时机分配。
在第4不扫描METADATA
表时可能会遇到一种复杂的情况:METADATA
表的Tablet还未分配之前是不能够扫描它的。
步骤3扫描过程中,如果发现Root Tablet还没有分配,Master就把Root Tablet 加入到未分配的Tablet集合。
上面这个附加操作确保了Root Tablet 会被分配。Root Tablet 包括了 所有METADATA
的Tablet的名字,意味着Master扫描完Root Tablet后就得到了所有METADATA
表的Tablet的名字了。
现有的Tablet集合只有在创建新表或者删除了旧表、两个 Tablet被合并了或Tablet被分割成两个小的Tablet时才会发生改变。
Master可以跟踪记录所有这些事件, 除了Tablet分割外的事件都是Master发起的的。
Tablet分割事件需要特殊处理,因为该事件是由Tablet 服务器发起的。
Tablet分割结束后,Tablet Server通过在METADATA
表添加Tablet的信息来提交这 个操作;分割结束后,Tablet Server会通知Master。
如果分割操信息已提交,却没有通知到Master(可能两个服务器中有一个宕机了),Master在要求Tablet服务器装载已经被分割 的子表的时候会发现一个新的Tablet。对比METADATA
表中Tablet的信息,Tablet Server会发现 Master要求其装载的Tablet并不完整,就会重新向Master发送通知信息,从而更新METADATA
表。
Tablet Server
Tablet的数据持久化存储在GFS中,具体持久化流程如下图所示。
Updates操作会先提交到log(WAL)中,log主要用来进行数据恢复的。所有的Updates中,最近提交的那部分会存放在排序的缓存中,这个缓存称为MemTable
,更早的Updates会存放在一系列SSTable
中,这些SSTable
本质上就是MemTablet
刷盘生成的。
为了恢复Tablet
,Tablet Server首先从MEMTABLE
中读取元数据信息,元数据信息包含组成该Tablet的SSTable列表及一系列重启点,这些重启点指向包含该Tablet数据的已提交日志记录,Tablet Server会把SSTable的索引读入内存,根据重启点恢复MemTable。
Tablet Server接收到数据写入请求时,Tablet Server首先要检查操作格式是否正确、操作发起者是否有执行这个操作的权限。权限验证的方法是根据从Chubby文件里读取出来的具有写权限的操作者列表来进行验证(这个文件几乎一定会存放在Chubby客户缓存里)。成功的修改操作会记录在提交日志里。可以采用批量提交的方式来提高大量小的修改操作的应用程序的吞吐量。
数据写如操作提交后,数据最终会被插入到MemTable
里。
Tablet Server接收到数据读取请求时,Tablet Server会作类似的完整性和权限检查。一个有效的读操作在一个由一系列SSTable和memtable合并的视图里执行的。由于SSTable和memtable是按字典排序的数据结构,因此可以高效生成合并视图。
Tablet合并和分割时,正在进行的读写操作能够继续进行。
Compaction(合并)
随着数据的不断写入,MemTable
占用的内存会不断增加。当MemTable
占用的内存超过一定阈值时,内存中的MemTable
会被冻结,切换为只读状态,同时创建一个新的MemTable
,新的数据写入请求会写入到新的MemTable
中,只读的MemTable
会被转换为SSTable
并最终写入底层存储系统(GFS)中,这个过程被称作小合并(Minor Compaction
)。
小合并的作用主要有两个:
降低Tablet Server的内存使用
在Tablet Server意外宕机时,降低从WAL恢复MemTable时需要读取的数据量。
每次小合并都会生成SSTable
,如果只有小合并,一直这么持续下去,那么,在Tablet Server接收到数据读取操作时,就需要充所有可能存在待检索row key
的SSTable
检索,然后合并所有更新操作,才能最终得到最新的value值。
为了避免上述这种情况发生,我们在后台周期性地执行大合并(Major Compaction)
,大合并会读取几个SSTable
,然后进行数据合并,合并结束后,即可将原先的SSTable
文件删除。
优化及改进
前面一个章节描述了BigTable的底层实现原理,不过,为了满足用户所需的高性能,高可用和可靠性。在具体实现时需要各种优化才行。
Locality Groups
客户端可以将多个列族组成Locality Graph
。每个Tablet会为Locality Group中的数据单独生成SSTable。
将通常不会一切访问的列族分离到单独的Locality Group
中,可以实现更高效的数据读取。
例如,可以将Webtable 中的页面元数据(例如,语言和检验和)放在同一Locality Group
中,叶绵绵的内容在不同组中,当应用程序想要读取页面的元数据信息时,不需要读取所有的页面内容即可完成。
此外,还可以针对每个Locality Grou
做相应的参数优化,例如,可以声明将某个Locality Group
放到内存中。
内存中Locality Group
对应的SSTable会被延迟加载到Tablet Server中,一旦加载完成,在不访问磁盘的情况下,实现Locality Group
数据访问,此功能对于频繁访问的小块数据十分有用,Google内部用来存储元数据表。
Compression(压缩)
客户端可以控制是否压缩Locality Group
的SSTables以及使用哪种方式进行压缩。
用户指定的压缩格式应用于每个SSTable Block(其大小可通过特定于局部性组的调整参数进行控制)。
通过单独压缩每个块会损失一些空间,但好处是可以读取SSTable的小部分,而无需对整个文件进行解压缩。
许多客户端使用两遍自定义压缩方案。第一遍压缩过程使用了Bentley和McIlroy的方案[6],在一个大范围内使用前缀压缩算法对普通的长字符串进行压缩。第二遍压缩使用了一个快速压缩算法,该算法在一个16kb的小窗口中寻找重复数据。两种压缩过程都非常快,现代机器上,它们的编码速度为100-200 MB/s,解码速度为400-1000 MB/s。尽管我们在选择压缩算法时强调的是速度而不是空间缩减,但这种两遍压缩方案做得非常好。
Caching(缓存)
为了提升数据读取性能,Tablet Server使用两级缓存。
Scan Cache
是Higher-Level缓存,该缓存会缓存SSTablet接口返回的Key-Value键值对。
Block Cache
是Lower-Level缓存,该缓存会缓存从GFS中读取的SSTable Block。
Scan Cache
对于需要频繁访问相同数据的应用程序来说是非常有用的。
Block Cache
则对需要访问临近数据的应用程序来说非常有用。
Bloom Filters(布隆过滤器)
如上个章节中对BigTable底层实现原理描述的一样,数据读取操作最终是从Tablet的SSTable中读取的。如果SSTable不再内存中,最终就需要通过读取磁盘来实现数据读取了。通过为特定Locality Group
的SSTable创建布隆过滤器,可以减少磁盘的访问次数。
布隆过滤器使得我们通过查询布隆过滤器来判断SSTable是否包含指定行/列的数据,对于某些应用程序,通过使用布隆过滤器可以显著降低Tablet Server的磁盘寻道次数。另外,使用布隆过滤器意味着对于不存在的行/列数据可以避免大量不必要的磁盘读取。
WAL(提交日志实现)
如果未每个Tablet都生成相应的WAL文件,那么GFS就需要同时写入很多文件,并发量很高,这种场景下,底层每个GFS服务器为了将日志数据写入不同的物理文件,会导致大量磁盘寻道,效率极低。此外,每个Tablet提交单独的日志文件也会降低批量提交优化性能,原因在与,由于分Tablet进行提交,对应的批量数据就回比较少。为了解决这些问题,我们将每个Talbet Server中所有的Tablet的数据写入日志追加到同一日志文件中,从而降低GFS的并发量,也降低底层GFS的物理磁盘寻道。
每个Tablet Server仅创建一个提交日志(WAL)文件,在正常操作场景下,可以大幅度提高性能,但数据恢复时却很复杂。
一台Tablet Server宕机时,其维护的所有Tablets将被转移到其他Tablet Server上,每台Tablet Server仅会装载少量原始Tablet Server的Tablet。为了恢复Tablet Server的状态,新的Tablet Server需要从原始Tablet写入的提交日志中重新应用该平板电脑的更新。然而,该宕机Tablet Server上的所有的Tablet的更新操作混合在同一个物理日志文件中。
一种方法是让每个新的Tablet Server读取完整的提交日志文件,并只应用它需要恢复的Tablet所需的条目。然而,在这种方案下,如果当前集群有100台机器从一台故障的Tablet Server上分别分配Tablet,那么日志文件将被读取100次(每台服务器一次)。
为了避免日志的重复读取,首先按照对提交日志条目进行排序。在已排序的输出中,特定Tablet的所有更新操作都是连续的,因此,可通过一次磁盘搜索和顺序读取有效地读取。为了并行排序,将日志文件按64MB切分,在不同的Tablet Server上并行排序。排序过程由Master协调,并指示每台Tablet Server需要从某些提交日志文件中恢复更新日志时启动。
WAL日志写入GFS有时会由于各种原因导致性能中断(例如,涉及写操作的GFS服务器计算机,或为到达三个GFS服务器的特定集合而穿越的网络路径遇到网络拥塞或负载过重)。
为了保护更新操作不受GFS延迟峰值的影响,每个Tablet Server实际上有两个日志写入线程,每个线程都写入自己的日志文件;这两个线程一次只有一个处于活动状态。如果对WAL日志文件的写入执行得很差,则日志文件写入将切换到另一个线程,提交日志队列中的更新操作将由新活动的日志写入线程写入。日志条目包含序列号,以便在恢复过程消除此日志线程切换过程中产生的重复条目。
加速Tablet恢复
如果Master将Tablet从一个Tablet Server移动到另一个Tablet Server,则源Tablet Server首先对该Tablet Server进行一次小合并。这种合并通过减少Tablet Server提交日志中未压缩状态的数量来缩短恢复时间。完成压缩后,Tablet Server停止为该Tablet提供服务。
在实际卸载Tablet之前,Tablet Server会执行另一次(通常非常快速)小合并,以消除执行第一次小合并时到达的Tablet Server日志中的任何剩余未压缩状态。完成第二次小压缩后,可以将Tablet加载到另一台Tablet Server上,而无需恢复任何日志条目。
总结
之所以写这篇博客,其实,是为了引出LevelDB ,LevelDB又是啥呢?
LevelDB一个单机的开源的高效的KV存储系统,该单机KV存储系统,可以说是高度复刻了BigTable中的Tablet,而BigTable毕竟不是开源哒,我们通过Google的这篇论文,也只是能了解到BigTable的整体架构,但是具体细节就只能YY,或者去看HBase(参考BigTable实现的一个开源分布式列式数据库)的源码了。
不过呢,出于工作需要呢,目前对HBase需求不大,更需要弄懂单机KV系统是如何实现的,所以呢,我就屁颠屁颠地区看LevelDB了,相比于BigTable/HBase,仅仅是单机和分布式的区别了,而且,LevelDB代码量更小,更容易学习和掌控,接下来,我会通过一系列笔记来记录和分享自己学习LevelDB设计原理及底层细节的过程,希望大家多多关注呀。
你可能感兴趣的:(缘起:BigTable)
我的创作纪念日
BoAiB
其他
机缘起初,只是因为这个平台学习知识很方便,慢慢的有了记录自己“成长”的想法,也很想一直坚持下去。收获获得了100+粉丝的关注获得了6000+正向的反馈,如赞、评论、阅读量等关注了许多榜样大神学习习惯也变得更好了,会很认真仔细的记录自己的收获,也很开心能被大家认可我的分享日常创作已经是我生活的一部分了一边学习,一边实践,一边记录以前总觉得,做笔记太浪费时间了,总觉得实践才是硬道理,现在想想,真是愚昧
Hadoop 发展过程是怎样的?
AI天才研究院
Python实战 自然语言处理 人工智能 语言模型 编程实践 开发语言 架构设计
作者:禅与计算机程序设计艺术1.简介2003年,美国加州大学洛杉矶分校教授李彦宏博士发明了一种分布式文件系统——GFS(GoogleFileSystem)。由于该文件系统设计得足够简单,可以适应大规模数据集存储需求,在此基础上演化出多种应用,包括MapReduce、BigTable、PageRank等,并成为当时互联网公司的标配技术之一。2004年,Google发布了第一版Hadoop项目,定位是
纯血Harmony NETX 5小游戏实践:贪吃蛇(附源文件)
我睡醒再说
HarmonyOS NETX原生态游戏 harmonyos 华为 动画 游戏
一、项目缘起:对鸿蒙应用开发的探索在鸿蒙系统生态逐渐丰富的当下,我一直想尝试开发一款简单又有趣的应用,以此深入了解鸿蒙应用开发的流程与特性。贪吃蛇作为经典游戏,规则易懂、逻辑清晰,非常适合用来实践。于是,基于鸿蒙的ArkTS语言,开启了这款“贪吃蛇大冒险”小游戏的开发之旅。二、核心逻辑拆解:构建游戏的“大脑”(一)数据结构与初始状态首先定义SnakeSegment接口,用于描述蛇的身体片段和食物的
分布式存储引擎OceanBase,UpdateServer 实现机制——存储引擎
「已注销」
数据库
UpdateServer存储引擎如下图所示。UpdateServer存储引擎与Bigtable存储引擎看起来很相似,不同点在于:UpdateServer只存储了增量修改数据,基线数据以SSTable的形式存储在Chunkserver上,而Bigtable存储引擎同时包含某个子表的基线数据和增量数据;UpdateServer内部所有表格共用MemTable以及SSTable,而Bigtable中每个
Go 语言的堆糖图片爬虫
Go Dgg
golang 爬虫 开发语言
基于Go语言的堆糖图片爬取探索之旅在互联网的浩瀚海洋中,堆糖网以其丰富多样的高清图片、美图壁纸等内容吸引了众多用户。对于图片爱好者来说,能高效获取心仪的图片资源无疑是一件极具吸引力的事情。今天,就带大家走进一段基于Go语言的堆糖图片爬取尝试之旅。一、缘起:对图片资源的渴求在日常的浏览和创作过程中,优质图片的需求日益增长。堆糖网上海量且风格各异的图片资源成为了理想的目标。然而,手动逐页浏览和下载不仅
python二维码识别读取_python+opencv检测图片中二维码
weixin_39875832
python二维码识别读取
缘起需要检测发票中二维码的位置,以确定图像该怎么旋转,同时也可以为提取二维码信息创造先觉条件!(万恶的需求!)失败的尝试--opencv训练大法不感兴趣的可跳过不看!解释:原文作者是训练检测舌头。。(蜜汁尴尬),先通过opencv自带的人脸检测cascade分类器进行人脸检测然后叠加训练的舌头分类器完成舌头的检测任务。不多说。我的实践:按照原作者的方法,换个数据集我来尝试一下。正样本:一波处理操作
GitLab CI/CD实践之GitLab Runner
天然玩家
架构设计 # GitLab ci devops gitlab runner gitlab
1缘起完成GitLab部署后,接下来开始做CI/CD测试,GitLab中通过流水线Pipeline完成CI/CD,于是开始使用Pipelines,可是使用时发现,即使添加了.gitlab-ci.yml文件,仍旧无法执行流水线,这让我想起了我做代码自动化扫描的经历,这段经历中,使用了流水线,非常感谢这段经历,让我快速意识到要配置GitLabRunner,使流水线运转起来。代码自动扫描是:每次提交代码
【赵渝强老师】HBase的体系架构
赵渝强老师
NoSQL数据库 hbase 架构 数据库 大数据 hadoop hdfs nosql
HBase是大表(BigTable)思想的一个具体实现。它是一个列式存储的NoSQL数据库,适合执行数据的分析和处理。简单来说,就是适合执行查询操作。从体系架构的角度看,HBase是一种主从架构,包含:HBaseHMaster、RegionServer和ZooKeeper,下图展示了这一架构。其中:HBaseHMaster负责Region的分配及数据库的创建和删除等操作。Regionserver负
20250620在Ubuntu20.04.6下编译KickPi的K7的Android14系统解决缺少libril.so.toc的问题
南棱笑笑生
杂质 杂质
20250620在Ubuntu20.04.6下编译KickPi的K7的Android14系统解决缺少libril.so.toc的问题2025/6/2016:19缘起:在Ubuntu20.04.6下编译KickPi的K7的Android14系统,报错:FAILED:ninja:'out/target/product/rk3576_u/obj_arm/SHARED_LIBRARIES/libril_i
20250615解决在ubuntu22.04.5下编译OK3576-C_Linux6.1.84_用户资料_R1出现问题sdb.c2410 fatal error sqlite3.h No such f
南棱笑笑生
杂质 c语言 sqlite 开发语言
20250615解决在ubuntu22.04.5下编译OK3576-C_Linux6.1.84_用户资料_R1出现问题sdb.c2410fatalerrorsqlite3.hNosuchfileordirectory2025/6/1521:11缘起:最近需要编译Rockchip瑞芯微的RK3576的Buildroot系统。想办法讲飞凌的、荣品的SDK合成一个近似Rockchip瑞芯微原厂的SDK。
20250615解决在ubuntu22.04.5下编译OK3576-C_Linux6.1.84_用户资料_R1出现问题special-case.h:12:10: fatal error: unicod
南棱笑笑生
杂质 c语言 sqlite 开发语言
20250615解决在ubuntu22.04.5下编译OK3576-C_Linux6.1.84_用户资料_R1出现问题special-case.h:12:10:fatalerror:unicode/uchar.h:Nosuchfileordirectory2025/6/1521:11缘起:最近需要编译Rockchip瑞芯微的RK3576的Buildroot系统。想办法讲飞凌的、荣品的SDK合成一个
HBase实战:大数据存储技术——学习HBase数据库的应用场景和使用技巧
AI天才研究院
Python实战 大数据 人工智能 语言模型 Java Python 架构设计
作者:禅与计算机程序设计艺术1.简介1.1HBase介绍ApacheHBase是一个分布式、可扩展、高性能的NoSQL数据库。它是一个列族数据库,由Apache基金会所开发。它支持稀疏和密集存储,提供了一个高度可伸缩的系统,并能够在线地进行横向扩展。HBase提供了一个高效率的数据访问接口,可以使用SQL或JavaAPI访问HBase数据库。HBase采用了Google的BigTable设计理念,
面试专区|【68道Hbase高频题整理(附答案背诵版)】
尺小闹
面试专区 面试 hbase 职场和发展
简述什么是Hbase数据库?Hbase是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,它利用HBase技术在HDFS上提供了类似于Bigtable的能力。换句话说,Hbase是ApacheHadoop生态系统中的一部分,可以为大数据应用提供快速的随机读写访问。为了更好地理解,我们可以将Hbase想象成一个巨大的表格,这个表格可以存储数十亿行和数百万列的数据。但与传统的关系型数据库不同,Hb
Hadoop复习(一)
丸卜
hadoop 大数据
初识Hadoop分别从选择题、大题和复习Linux命令来复习选择题问题1单项选择难度级别32分下面哪一个不属于Google的三驾马车?答案选项组GFSNDFSBigTableMapReduce问题2单项选择难度级别32分Hadoop3.x版本支持最低的JDK版本是()答案选项组JDK6JDK8JDK9JDK7问题3多项选择难度级别32分Hadoop的缺点有哪些答案选项组不适合处理小文件只适合处理离
mysql prepare statement
robch
数据库 mysql android 数据库
在MySQL中,PREPARE和EXECUTE语句可以用来执行预编译的SQL语句。然而,MySQL的语法略有不同于你提供的示例。以下是在MySQL中正确使用PREPARE和EXECUTE的示例:--PreparethestatementPREPAREstmtFROM'SELECT*FROMbigtableWHEREname=?';--Executethepreparedstatementwitha
68道Hbase高频题整理(附答案背诵版)
编程大全
面试题 hbase 数据库 大数据
简述什么是Hbase数据库?Hbase是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,它利用HBase技术在HDFS上提供了类似于Bigtable的能力。换句话说,Hbase是ApacheHadoop生态系统中的一部分,可以为大数据应用提供快速的随机读写访问。为了更好地理解,我们可以将Hbase想象成一个巨大的表格,这个表格可以存储数十亿行和数百万列的数据。但与传统的关系型数据库不同,Hb
深度探索Docker镜像标签管理
意倾城
Docker学习 docker
目录一、问题的缘起:一个看似简单的报错二、认知误区:我以为的"常识"其实是错的1.最初的误解2.Docker的实际情况三、技术验证:用实验打破认知实验1:基础标签行为实验2:运行时的默认行为实验3:多版本共存四、机制解析:Docker标签的底层逻辑1.标签的本质2.默认行为的实现五、解决方案的演进思考方案1:手动打标签(初级方案)方案2:构建时多标签(中级方案)方案3:CI/CD集成(高级方案)六
Java 设计模式心法之第1篇 - 缘起:告别“救火队员”,拥抱架构思维
码觉客
Java 设计模式心法 java 设计模式 架构
午夜时分,你是否仍在调试那个牵一发而动全身的“祖传”模块?面对日益膨胀、逻辑缠绕的系统,你是否感觉自己更像个四处堵漏的“救火队员”,而非运筹帷幄的工程师?本文作为《Java设计模式心法》的开篇,将直击痛点,剖析“代码能跑就好”背后的技术债危机,揭示为何良好的设计并非奢侈品,而是高质量软件的生命线。我们将探讨设计模式作为应对复杂度的“银弹匣”(而非银弹),如何帮助我们提升代码的可维护性、扩展性和健壮
谈谈云计算部署方式——关于分布化实现
chaoqunz
云计算 云计算 消息中间件 算法 存储 任务 session
转:http://labs.chinamobile.com/mblog/107231_26831前言:我们在以前的文章(对云计算中几种基础设施(Dynamo,Bigtable,Map/Reduce等)的朴素看法)中对云计算的概念和基础组织已作了较为详细的解释和分析,这次我们将继续云计算的话题——进一步谈谈云计算在实际应用环境中的部署方法。我个人理解,云的主要精髓之一(除此以外,资源虚拟化动态分配和
Google云计算原理和应用之分布式锁服务Chubby
谢苏大神
云计算 分布式
Chubby是Google设计的提供粗粒度锁服务的一个文件系统,它基于松耦合分布式系统,解决了分布的一致性问题。通过使用Chubby的锁服务,用户可以确保数据操作过程中的一致性。不过值得注意的是,这种锁只是一种建议性的锁(AdvisoryLock)而不是强制性的锁,这种选择系统具有更大的灵活性。GFS使用Chubby选取一个GFS主服务器,Bigtable使用Chubby指定锁一个主器并发现,控制
20250427在ubuntu16.04.7系统上编译NanoPi NEO开发板的FriendlyCore系统解决问题mkimage not found
南棱笑笑生
杂质 杂质
20250427在ubuntu16.04.7系统上编译NanoPiNEO开发板的FriendlyCore系统解决问题mkimagenotfound2025/4/279:19缘起:使用NanoPiNEO开发板,编译FriendlyCore系统,编译内核的时候报错。./build.shuboot-buildubootonlyCCdrivers/leds/trigger/ledtrig-default-
ollama环境变量配置:修改ollama的数据路径(安装路径)
正经教主
AI deepseek ollama 服务器 运维 ai llama 人工智能
缘起:目前的Ollama会默认安装到C盘,路径如下:C:\Users%username%\AppData\Local\Programs\Ollama,并不会让用户自定义选择安装路径。这样一来,ollama安装模型,如果很大,会占用C盘空间,影响系统运行速度,通过设置环境变量,来改变ollama模型放目录的地址。操作:需要关闭ollama。打开系统的“设置”:点击系统-系统信息:然后,点击“高级系统
第4章 分布式数据库HBase(又是一篇呕心力作,一文详讲HBase)
wyz191
大数据技术原理与应用 - 概念 存储 处理 分析与应用 大数据 hbase
HBase是谷歌BigTable的开源实现,是一个高可靠、高性能、面向列、可伸缩的分布式数据库,主要用来存储非结构化和半结构化的松散数据。适合于存储大表数据(表的规模可以达到数十亿行以及数百万列),并且对大表数据的读、写访问可以达到实时级别。利用HadoopHDFS(HadoopDistributedFileSystem)作为其文件存储系统,提供实时读写的分布式数据库系统。利用ZooKeeper作
【LuatOS】Lua与LuatOS中的Math.randomseed
不喝水的鱼儿
lua LuatOS 随机数
【LuatOS】Lua与LuatOS中的Math.randomseed0x00缘起0x01环境0x02实验测试代码实验方法实验结果1.本地Lua环境实验结果2.在线Lua环境实验结果3.本地LuatOS环境实验结果4.在线LuatOS实验结果实验总结0x03结论0x04资源0x05后记0x00缘起在Lua或者LuatOS虚拟机中,可以使用math.randomseed()进行置随机数种子,然后使用
DeepSeek 教我 C++ (6) : C++17 filesystem 的技巧
ZhiqianXia
DeepSeek 教我C++ c++ java 开发语言
缘起C++是个人最常用的编程语言,以前学生时代好多笔记都丢失了,想用DeepSeek帮忙快速整理一些编程细节,看看有没有没看到过的解释.提问:整理一下C++17filesystem常用方法以下是C++17std::filesystem常用方法的整理,按功能分类:1.头文件与命名空间#includenamespacefs=std::filesystem;//简化命名空间2.路径操作(fs::path
[转]LevelDB原理探究与代码分析
黑夜路人(heiyeluren)
Java/C/C++ leveldb db dbm kv hash db
LevelDB原理探究与代码分析1.概述LevelDB(http://code.google.com/p/leveldb/)是google开源的Key/Value存储系统,它的committer阵容相当强大,基本上是bigtable的原班人马,包括像jeffdean这样的大牛,它的代码合设计非常具有借鉴意义,是一种典型的LSMTree的KV引擎的实现,从它的数据结构来看,基本就是sstable的开
levelDB-Java源码分析
chenglao1975
java 数据结构与算法 数据库
levelDB是BigTable的单机版实现,是目前非常流行的存储引擎。用一句话概括levelDB:简约而不简单。简约体现在他的设计思想清楚明了,它的实现简洁,代码量较少。他的设计思想同时也是不简单的,值得仔细研究,实现细节,有很多值得深思的地方。本篇文章作为解析levelDB源码的初版,会有不完善、甚至不正确的地方,敬请谅解。java版本的源码,参见https://github.com/dain
LevelDB原理探究与代码分析
jlaij
c/c++ 算法/数据结构 levelDB 数据结构 代码分析
1.概述LevelDB(http://code.google.com/p/leveldb/)是google开源的Key/Value存储系统,它的committer阵容相当强大,基本上是bigtable的原班人马,包括像jeffdean这样的大牛,它的代码合设计非常具有借鉴意义,是一种典型的LSMTree的KV引擎的实现,从它的数据结构来看,基本就是sstable的开源实现,而且针对各种平台作了po
【解决方案】RAG实践:ES混合搜索BM25+kNN(cosine)
天然玩家
# ElasticSearch 解决方案 elasticsearch RAG 混合搜索 LLM 大模型
1缘起最近在研究与应用混合搜索,存储介质为ES,ES作为大佬牌数据库,非常友好地支持关键词检索和向量检索,当然,支持混合检索(关键词检索+向量检索),是提升LLM响应质量RAG(Retrieval-augmentedGeneration)的一种技术手段,那么,如何通过ES实现混合搜索呢?请看本篇文章。本系列分为两大部分:实践和理论。先讲实践,应对快速开发迭代,可快速上手实践;再讲理论,应对优化,如
Python 爬虫:一键解锁 3GPP 标准协议下载难题
youngerwang
Python 5G 移动通信 python 爬虫 3gpp标准协议 反爬技巧
文章目录【背景说明】零、缘起一、核心算法设计1.**分层遍历算法(BFS)**2.**下载控制算法**3.**路径生成算法**二、关键数据结构三、可靠性增强设计1.**网络容错机制**2.**数据完整性保障**3.**系统兼容性设计**四、反爬虫对抗策略1.**基础反反爬技术**2.**高级防护建议(暂未实现,后续补充)**五、性能优化权衡(暂未实现,后续补充)六、合规性考量七、总结八、Pytho
辗转相处求最大公约数
沐刃青蛟
C++ 漏洞
无言面对”江东父老“了,接触编程一年了,今天发现还不会辗转相除法求最大公约数。惭愧惭愧!
为此,总结一下以方便日后忘了好查找。
1.输入要比较的两个数a,b
忽略:2.比较大小(因为后面要的是大的数对小的数做%操作)
3.辗转相除(用循环不停的取余,如a%b,直至b=0)
4.最后的a为两数的最大公约数
&
F5负载均衡会话保持技术及原理技术白皮书
bijian1013
F5 负载均衡
一.什么是会话保持? 在大多数电子商务的应用系统或者需要进行用户身份认证的在线系统中,一个客户与服务器经常经过好几次的交互过程才能完成一笔交易或者是一个请求的完成。由于这几次交互过程是密切相关的,服务器在进行这些交互过程的某一个交互步骤时,往往需要了解上一次交互过程的处理结果,或者上几步的交互过程结果,服务器进行下
Object.equals方法:重载还是覆盖
Cwind
java generics override overload
本文译自StackOverflow上对此问题的讨论。
原问题链接
在阅读Joshua Bloch的《Effective Java(第二版)》第8条“覆盖equals时请遵守通用约定”时对如下论述有疑问:
“不要将equals声明中的Object对象替换为其他的类型。程序员编写出下面这样的equals方法并不鲜见,这会使程序员花上数个小时都搞不清它为什么不能正常工作:”
pu
初始线程
15700786134
暑假学习的第一课是讲线程,任务是是界面上的一条线运动起来。
既然是在界面上,那必定得先有一个界面,所以第一步就是,自己的类继承JAVA中的JFrame,在新建的类中写一个界面,代码如下:
public class ShapeFr
Linux的tcpdump
被触发
tcpdump
用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具。 tcpdump可以将网络中传送的数据包的“头”完全截获下来提供分析。它支 持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来帮助你去掉无用的信息。
实用命令实例
默认启动
tcpdump
普通情况下,直
安卓程序listview优化后还是卡顿
肆无忌惮_
ListView
最近用eclipse开发一个安卓app,listview使用baseadapter,里面有一个ImageView和两个TextView。使用了Holder内部类进行优化了还是很卡顿。后来发现是图片资源的问题。把一张分辨率高的图片放在了drawable-mdpi文件夹下,当我在每个item中显示,他都要进行缩放,导致很卡顿。解决办法是把这个高分辨率图片放到drawable-xxhdpi下。
&nb
扩展easyUI tab控件,添加加载遮罩效果
知了ing
jquery
(function () {
$.extend($.fn.tabs.methods, {
//显示遮罩
loading: function (jq, msg) {
return jq.each(function () {
var panel = $(this).tabs(&
gradle上传jar到nexus
矮蛋蛋
gradle
原文地址:
https://docs.gradle.org/current/userguide/maven_plugin.html
configurations {
deployerJars
}
dependencies {
deployerJars "org.apache.maven.wagon
千万条数据外网导入数据库的解决方案。
alleni123
sql mysql
从某网上爬了数千万的数据,存在文本中。
然后要导入mysql数据库。
悲剧的是数据库和我存数据的服务器不在一个内网里面。。
ping了一下, 19ms的延迟。
于是下面的代码是没用的。
ps = con.prepareStatement(sql);
ps.setString(1, info.getYear())............;
ps.exec
JAVA IO InputStreamReader和OutputStreamReader
百合不是茶
JAVA.io操作 字符流
这是第三篇关于java.io的文章了,从开始对io的不了解-->熟悉--->模糊,是这几天来对文件操作中最大的感受,本来自己认为的熟悉了的,刚刚在回想起前面学的好像又不是很清晰了,模糊对我现在或许是最好的鼓励 我会更加的去学 加油!:
JAVA的API提供了另外一种数据保存途径,使用字符流来保存的,字符流只能保存字符形式的流
字节流和字符的难点:a,怎么将读到的数据
MO、MT解读
bijian1013
GSM
MO= Mobile originate,上行,即用户上发给SP的信息。MT= Mobile Terminate,下行,即SP端下发给用户的信息;
上行:mo提交短信到短信中心下行:mt短信中心向特定的用户转发短信,你的短信是这样的,你所提交的短信,投递的地址是短信中心。短信中心收到你的短信后,存储转发,转发的时候就会根据你填写的接收方号码寻找路由,下发。在彩信领域是一样的道理。下行业务:由SP
五个JavaScript基础问题
bijian1013
JavaScript call apply this Hoisting
下面是五个关于前端相关的基础问题,但却很能体现JavaScript的基本功底。
问题1:Scope作用范围
考虑下面的代码:
(function() {
var a = b = 5;
})();
console.log(b);
什么会被打印在控制台上?
回答:
上面的代码会打印 5。
&nbs
【Thrift二】Thrift Hello World
bit1129
Hello world
本篇,不考虑细节问题和为什么,先照葫芦画瓢写一个Thrift版本的Hello World,了解Thrift RPC服务开发的基本流程
1. 在Intellij中创建一个Maven模块,加入对Thrift的依赖,同时还要加上slf4j依赖,如果不加slf4j依赖,在后面启动Thrift Server时会报错
<dependency>
【Avro一】Avro入门
bit1129
入门
本文的目的主要是总结下基于Avro Schema代码生成,然后进行序列化和反序列化开发的基本流程。需要指出的是,Avro并不要求一定得根据Schema文件生成代码,这对于动态类型语言很有用。
1. 添加Maven依赖
<?xml version="1.0" encoding="UTF-8"?>
<proj
安装nginx+ngx_lua支持WAF防护功能
ronin47
需要的软件:LuaJIT-2.0.0.tar.gz nginx-1.4.4.tar.gz &nb
java-5.查找最小的K个元素-使用最大堆
bylijinnan
java
import java.util.Arrays;
import java.util.Random;
public class MinKElement {
/**
* 5.最小的K个元素
* I would like to use MaxHeap.
* using QuickSort is also OK
*/
public static void
TCP的TIME-WAIT
bylijinnan
socket
原文连接:
http://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux.html
以下为对原文的阅读笔记
说明:
主动关闭的一方称为local end,被动关闭的一方称为remote end
本地IP、本地端口、远端IP、远端端口这一“四元组”称为quadruplet,也称为socket
1、TIME_WA
jquery ajax 序列化表单
coder_xpf
Jquery ajax 序列化
checkbox 如果不设定值,默认选中值为on;设定值之后,选中则为设定的值
<input type="checkbox" name="favor" id="favor" checked="checked"/>
$("#favor&quo
Apache集群乱码和最高并发控制
cuisuqiang
apache tomcat 并发 集群 乱码
都知道如果使用Http访问,那么在Connector中增加URIEncoding即可,其实使用AJP时也一样,增加useBodyEncodingForURI和URIEncoding即可。
最大连接数也是一样的,增加maxThreads属性即可,如下,配置如下:
<Connector maxThreads="300" port="8019" prot
websocket
dalan_123
websocket
一、低延迟的客户端-服务器 和 服务器-客户端的连接
很多时候所谓的http的请求、响应的模式,都是客户端加载一个网页,直到用户在进行下一次点击的时候,什么都不会发生。并且所有的http的通信都是客户端控制的,这时候就需要用户的互动或定期轮训的,以便从服务器端加载新的数据。
通常采用的技术比如推送和comet(使用http长连接、无需安装浏览器安装插件的两种方式:基于ajax的长
菜鸟分析网络执法官
dcj3sjt126com
网络
最近在论坛上看到很多贴子在讨论网络执法官的问题。菜鸟我正好知道这回事情.人道"人之患好为人师" 手里忍不住,就写点东西吧. 我也很忙.又没有MM,又没有MONEY....晕倒有点跑题.
OK,闲话少说,切如正题. 要了解网络执法官的原理. 就要先了解局域网的通信的原理.
前面我们看到了.在以太网上传输的都是具有以太网头的数据包. 
Android相对布局属性全集
dcj3sjt126com
android
RelativeLayout布局android:layout_marginTop="25dip" //顶部距离android:gravity="left" //空间布局位置android:layout_marginLeft="15dip //距离左边距
// 相对于给定ID控件android:layout_above 将该控件的底部置于给定ID的
Tomcat内存设置详解
eksliang
jvm tomcat tomcat内存设置
Java内存溢出详解
一、常见的Java内存溢出有以下三种:
1. java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出JVM在启动的时候会自动设置JVM Heap的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)不可超过物理内存。
可以利用JVM提
Java6 JVM参数选项
greatwqs
java HotSpot jvm jvm参数 JVM Options
Java 6 JVM参数选项大全(中文版)
作者:Ken Wu
Email:
[email protected]
转载本文档请注明原文链接 http://kenwublog.com/docs/java6-jvm-options-chinese-edition.htm!
本文是基于最新的SUN官方文档Java SE 6 Hotspot VM Opt
weblogic创建JMC
i5land
weblogic jms
进入 weblogic控制太
1.创建持久化存储
--Services--Persistant Stores--new--Create FileStores--name随便起--target默认--Directory写入在本机建立的文件夹的路径--ok
2.创建JMS服务器
--Services--Messaging--JMS Servers--new--name随便起--Pers
基于 DHT 网络的磁力链接和BT种子的搜索引擎架构
justjavac
DHT
上周开发了一个磁力链接和 BT 种子的搜索引擎 {Magnet & Torrent},本文简单介绍一下主要的系统功能和用到的技术。
系统包括几个独立的部分:
使用 Python 的 Scrapy 框架开发的网络爬虫,用来爬取磁力链接和种子;
使用 PHP CI 框架开发的简易网站;
搜索引擎目前直接使用的 MySQL,将来可以考虑使
sql添加、删除表中的列
macroli
sql
添加没有默认值:alter table Test add BazaarType char(1)
有默认值的添加列:alter table Test add BazaarType char(1) default(0)
删除没有默认值的列:alter table Test drop COLUMN BazaarType
删除有默认值的列:先删除约束(默认值)alter table Test DRO
PHP中二维数组的排序方法
abc123456789cba
排序 二维数组 PHP
<?php/*** @package BugFree* @version $Id: FunctionsMain.inc.php,v 1.32 2005/09/24 11:38:37 wwccss Exp $*** Sort an two-dimension array by some level
hive优化之------控制hive任务中的map数和reduce数
superlxw1234
hive hive优化
一、 控制hive任务中的map数: 1. 通常情况下,作业会通过input的目录产生一个或者多个map任务。 主要的决定因素有: input的文件总个数,input的文件大小,集群设置的文件块大小(目前为128M, 可在hive中通过set dfs.block.size;命令查看到,该参数不能自定义修改);2. 
Spring Boot 1.2.4 发布
wiselyman
spring boot
Spring Boot 1.2.4已于6.4日发布,repo.spring.io and Maven Central可以下载(推荐使用maven或者gradle构建下载)。
这是一个维护版本,包含了一些修复small number of fixes,建议所有的用户升级。
Spring Boot 1.3的第一个里程碑版本将在几天后发布,包含许多