关于lucene:Lucene-中的-VInt

零 版本Lucene-Core 版本 8.8.2 一 简介Lucene 的 Index 设计根本依赖磁盘存储,而倒排索引是依赖大量冗余数据来实现分词搜寻的技术,所以 Lucene 在设计的时候用了很多工夫换空间的数据压缩技术,以此保障能在起码的磁盘资源来贮存最多的数据。VInt 就是其中一个很有意思的结构设计。 二 技术原理1 概要Java 中一个一般的 int 占据 4 个 byte。然而当 int 的值为 -128 ~ 127 的时候,其实只须要一个 byte 就能够放得下了,其它三个 byte 都是无意义的冗余(其它几个 byte 所能代表的区间以此类推),实在可能用满这四个 byte 的状况并不多。VInt 的意思是 variant int,也就是可变的 int。其本质是按需分配,缩小这种冗余。 2 byte 批示位一个失常的 byte 有八个数据无效位,而 VInt 中只有七个,最高位变成了后一个 byte 的批示位。 最高位为 1,代表后一个 byte 仍然是以后数据最高位为 0,代表前面没有数据了 3 VInt 的副作用对于负数来说,因为只有七个数据位,所以当 int 的值比拟大的时候,可能会须要 5 个 byte 能力表述以后的数据(这个问题无奈被解决,VInt 也感觉无需解决,因为状况在实在生产中并不多)对于正数来说,最高位为 1,无奈被压缩(引入 zigzag 编码) 4 zigzag 编码应用位移和异或操作将首位的符号位挪到数据的最初一位。 ...

May 29, 2022 · 3 min · jiezi

关于lucene:再聊聊ES索引文档的流程

文档索引步骤 客户端向node1发送新建,查问或删除申请。节点应用文档的_id确定文档属于分片0,申请会被转发到node3,因为分片0的主分片目前被调配在node3上node3在主分片下面执行申请,如果胜利了,它会将申请并行转化到node1与node2的正本分片上,一旦所有的正本分片都报告胜利,node3将向协调节点报告胜利,协调节点向客户端报告胜利。下面是按单个文档操作的,多个文档在应用bulk操作时和下面流程差不多,这里不再多说。 文档索引过程详解整体流程图。 协调节点默认应用文档ID参加计算(也反对通过routing), 以便为路由提供适合的分片。 shard = hash(document_id) % (num_of_primary_shards)当分片所在的节点接管到来自协调节点的申请后,会将申请写入到memory buffer,而后定时(默认1秒)写入到filesystem cache(操作系统文件缓存,这里不禁JVM治理),从memory buffer到filesystem cache的过程就叫refresh。须要留神的是数据写入memory buffer后并不以马上被检索,而只有通过refresh写入到filesystem caceh后也就是写入到segment之后,此时文档才能够被检索到。因为memory buffer与filesystem cache都还未写入磁盘所以会有失落的可能。ES是通过translog机制来保证数据的可靠性的。在接管到申请后,同时也会写入到translog,当filesystem cache中的数据写入到磁盘后才会革除translog里的数据,这个过程称flush。flush是定时触发(默认30分钟)或translog变得太大(默认为512MS)。并发下的update流程ES应用版本号这种乐观锁的机制解决并发批改问题,ES保障了一个老版本的数据永远无奈重写或笼罩更新版本的数据,如果因版本号抵触批改失败能够应用retry_on_conflict参数设定重试次数。流程如下: 收到update申请后,从segment或者translog中读取同id的Doc,并获取此时版本号。将第1步版本号对应的全量Doc和申请中的局部字段合并为一个残缺的Doc,同时更新内存中的versionMap。这个时候update申请相当于一个index申请了。加锁。再次从versionMap中读取该id最大版本号,如果versionMap没有,则从segment或translog里读。查看版本号是否抵触(查看第1步与第4步的版本号是否雷同,雷同为不抵触,不雷同为抵触),如果抵触则回退到开始的update doc阶段从新执行;如果没抵触则执行最新的add申请。在index doc阶段,首先将version+1,再将doc退出到lucene中,lucene会先删除同id下已存在的doc id,而后再减少新doc,写入lucene胜利后,将更新后的版本号更新到versionMap。开释锁,局部更新流程完结。ES里的translogES为了缩小磁盘IO保障读写性能,个别是每隔一段时间(比方5分钟)才会将segment写入磁盘长久化,对于还未flush到磁盘的数据,如果产生宕机或掉电,那么内存里的数据是会失落的,ES是如何保证数据的可靠性的呢?这里咱们来说下translog。在每个shard中,写入流程分两局部,先写入lucene,再写入到translog。写完lucene文件创建好索引后,此时索引还在内存里,接着去写translog,写完translog后,刷新translog数据到磁盘上(这个是可配置的,可能会立刻flush到磁盘也可能距离一段时间再flush),写磁盘胜利后,申请返回用户。这里有几个关键点: 一是和数据库不同,数据库是先写commitlog,而后再写内存,而ES是先写内存再写translog,一种可能起因是lucene内存写入有很简单的逻辑,容易失败,比方分词,字段长度超限等,为了防止translog里有大量有效记录,就将写内存放到了后面二是写入内存后,并不是可搜寻的,须要通过refresh将内存的对象转换成残缺的segment后,而后再次reopen后能力被搜寻,个别这个工夫设置为1秒,这也是ES被称为NRT(near real time)的起因三是当ES作为nosql数据库时,查问形式是getDocById,这种查问能够间接从translog中查问(translog是以key/value模式写入的,key是_id,value是Doc内容),这时就成了RT实时零碎了。四是每隔一段较长时间,比方30分钟后,lucene会将内存中生成的segment刷新到磁盘上,刷新后的索引文件曾经长久化了,历史的translog会被清掉个性总结可靠性:因为lucene的设计不思考可靠性,在ES中通过replica和translog两套机制保证数据的可靠性一致性:lucence中的flush锁只保障update接口里的delete和add两头不会flush,然而add实现后依然有可能立刻产生flush,导致segment可读,这样就没法保障primary和其余replica能够同一时间flush,进而呈现查问不稳固的状况,这里只能实现最终一致性。原子性:add与delete都是间接调用lucene的接口,是原子的。当局部更新时,应用version和锁保障更新是原子的。隔离性:依然采纳version和部分锁来保住更新的是特定版本的数据实时性:应用定期refresh segment到内存,并且reopen segment形式保障搜寻能够在较短时间(比方1秒)内被搜寻到。通过将未刷新到磁盘数据记入translog,保障对未提交数据能够通过ID实时拜访到

February 16, 2022 · 1 min · jiezi

关于lucene:lucene里的segment

这章来记录一下lucene里的segment。segment是索引中最小的独立存储单元。一个索引文件由一个或多个段组成。segment外部次要有: Inverted IndexSorted FieldsDocument ValuesCache Inverted Index最为重要,它次要包含两局部: 一个有序的数据字典(包含单词Term和它呈现的频率)与单词Term对应的Postings(即倒排表,存单词的文件)当咱们搜寻时,首先将搜寻的内容合成,而后在字典里找到对应的Term,从而查找到与搜寻相干的文件内容。依据上图内容,举几个查问例子。 查问'the fury'还记得上一章介绍的lucene四种检索里的‘AND’形式吗?Lucene基本知识主动补全(AutoCompletion-Prefix)如果想查找字母‘c‘结尾的单词,可能简略通过二分查找在Inverted Index表中找到例如'choice','coming'这样的词(Term)低廉的查找如果想要查找所有蕴含'our'字母的单词,那么零碎会扫描整个Inverted Index,这是十分低廉的。在此状况下,如果想要做优化,那么咱们面对的问题是如何生成适合的Term。个别有上面这些计划:1) suffix -> xiffus ,如果咱们想当前缀作为搜寻条件,能够为Term做反向解决2) (60.6384, 6.5017) -> u4u8gyykk对于GEO地位信息,能够将它转换成GEO Hash3) 123 -> {1-hundreds, 12-tens, 123}对于简略的数字,能够为它生成多重模式的Term解决拼写错误一个python库为单词生成了一个蕴含谬误拼写信息的树形状态机,解决拼写错误的问题。Stored Field字段查找(待具体补充)当咱们想要查找蕴含某个特定题目内容的文件时,Inverted Index就不能很好的解决这个问题,所以lucene提供了另外一种数据结构Stored Fields来应答这个问题,实质上,Stored Fields是一个简略的键值对key-value。默认状况下,ES会存储整个文件的JSON source. Document Values为了排序,聚合(待具体补充)Document values是为了解决排序,聚合,facet问题的,DV构造实质上是一个列式的存储,它高度优化了具备雷同类型的数据的存储构造。为了提高效率,ES能够将索引下某一个Document Value全副读取到内存中进行操作,这大大晋升访问速度,然而也会耗费大量的内存空间。 参考文章:ES详解 - 原理:从图解构筑对ES原理的初步认知

February 16, 2022 · 1 min · jiezi

关于lucene:Lucene基本知识

Lucene采纳了基于倒排表的设计原理,能够十分高效的实现文本查找,在底层采纳了分段的存储模式,使它在读写时简直完全避免锁的呈现,大大晋升了读写性能。 外围模块lucene的写流程和读流程如图所示。其中,虚线箭头(a,b,c,d)示意写索引的次要过程,实线箭头(1-9)示意查问的次要过程。lucene的次要模块(可联合上图) analysis模块:次要负责词法剖析及语言解决,也就是常说的分词,通过该模块可最终造成存储或搜寻的最小单元Term。index模块:次要负责索引的创立工作。store模块:次要负责索引的读写,次要是对文件的一些操作,其次要目标是形象出和平台文件系统无关的存储。queryParser:次要负责语法分析,把咱们的查问语句生成Lucene底层能够辨认的条件。search模块:次要负责对索引的搜寻工作similarity模块:次要负责相差性打分和排序的实现外围术语Term:是索引里最小的存储和查问单元,对于英文来说个别指一个单词,对于中文来说个别指一个分词后的词。词典(Term Dictionary):是Term的汇合。词典的数据结构有多种,比方排序数组通过二分查找来检索数据;HashMap较排序数据快但占用空间更多;fst(finite-state transducer)有更高的数据压缩率与查问效率。fst是默认的数据结构。倒排表:一篇文章通常由多个词组成,倒排表记录的是某个词在哪些文章中呈现过正向信息:原始的文档信息,能够用来做排序,聚合与展现等。段(segment):索引中最小的独立存储单元。一个索引文件由一个或多个段组成。在Lucene中的段有不变性,段一旦生成,在其上只能有读rket,不能有写操作Lucene的底层存储格局如下图所示。其中的字典就是Term汇合。词典中的Term指向的文档链表的汇合叫倒排表。词典与倒排表是实现疾速检索的重要根底,它们是分两局部存储的,在倒排表中岂但存储了文档编号,还存储了词频等信息。 检索形式在Lucene的查问过程中次要检索形式有上面四种。 单个词查问指对一个Term进行查问,比方查找蕴含字符串‘lucene'的文档,则只须要词典中找到Term 'lucene',再取得在倒排表中对应的文档链表即可。AND批对多个汇合求交加。比方查找既蕴含字符串‘lucene'又蕴含字符串‘solr‘的文档,则查找步骤如下:1) 在词典中找到Term 'lucene',失去‘lucene‘对应的文档链表。2) 在词典中找到Term 'solr',失去‘solr‘对应的文档链表。3) 合并链表,对两个文档链表做交加运算。OR指对多个汇合求并集。比方,若要查找蕴含字符串“lucene”或者蕴含字符串“solr”的文档,则查找步骤如下。1) 在词典中找到Term“lucene”,失去“lucene”对应的文档链表。2) 在词典中找到Term“solr”,失去“solr”对应的文档链表。3) 合并链表,对两个文档链表做并集运算,合并后的后果蕴含“lucene”或者蕴含“solr”。NOT指对多个汇合求差集。比方,若要查找蕴含字符串“solr”但不蕴含字符串“lucene”的文档,则查找步骤如下。1) 在词典中找到Term“lucene”,失去“lucene”对应的文档链表。2) 在词典中找到Term“solr”,失去“solr”对应的文档链表。3) 合并链表,对两个文档链表做差集运算,用蕴含“solr”的文档集减去蕴含“lucene”的文档集,运算后的后果就是蕴含“solr”但不蕴含“lucene”.通过上述四种查问形式,咱们能够晓得,因为Lucene是以倒排表的模式存储的,所以在Lucene的查找过程中只需在词典中找到这些Term,依据Term取得文档链表,而后依据具体的查问条件对链表进行交,并,差等操作,就能够精确地查到咱们想要的后果。 分段存储晚期全文检索为整个文档汇合建设一个很大的倒排索引并将其写入磁盘,如果有更新,就须要从新创立一个索引来代替原来的索引。显然这种形式在数据量大的时候效率很低。当初,在搜寻中引入了段的概念,每个段都是一个独立的可被搜寻的数据集,并且段具备不可变性,一旦索引的数据被写入磁盘就不可再批改。在分段思维下,对数据写操作的过程如下: 新增。当有新的数据须要创立索引时,因为段的不变性,所以抉择新建一个段来存储新增的数据。删除。当须要删除数据时,因为数据的在的段只可读不可写,所以Lucene在索引文件下新增了了一个.del文件,用来专门存储被删除的数据id,当查问时,被删除的数据还是能够被查到,只是在进行文档链表合并时,才将曾经删除的数据过滤掉。被删除的数据在进行段合并时才会真正被移除。更新。更新操作其实就是删除和新增的组合,先在.del文件中记录旧数据,再在新的段中增加一条更新后的数据。段不变的长处 不须要锁。因为数据不会更新,所以不必思考多线程下的读写不统一问题能够常驻外在。段在被加载到外在后,因为不变性,所以只有外在的空间足够大,就能够长时间驻存,大部分查问申请会间接拜访内存而不须要拜访磁盘绑在敌对。在段的申明周期内始终无效,不须要在每次数据更新时被重建增量创立。分段能够做到增量创立索引,能够轻量级对数据进行更新,因为每次创立的老本很低,所以能够频繁地更新数据,使零碎靠近实时更新。段不变的毛病 空间节约。对数据进行删除时,旧数据不会被马上删除,只有到段合并时才会移除,这样会节约大量空间更新时节约空间。更新是由新建与删除两个动作组成,也会节约不少空间服务器资源耗费大。因为索引具备不变性,所以每次更新数据时都须要新增一个段来存储数据。当段的数量过多时,对服务器的资源(如文件句柄)的耗费十分大,也会影响到查问性能。查问时须要过滤删除数据。在查问后须要对曾经删除的旧数据进行过滤,会减少查问的累赘。为了晋升写的性能。Lucene并没有每新增一条数据就减少一个段,而是采纳提早写的策略,每当有新增的数据时,就将其先写入内存中,而后批量写入磁盘中。若有一个段被写到磁盘,就会生成一个提交点,提交点就是一个用来记录所有提交后的段信息的文件。一个段一旦领有了提交点,就阐明这个段只有读的权限没写的权限;相同,当段在内存中时,就只有写数据权限而没有读数据权限,所以也就不能被检索了。因而从严格意义上来说Lucene或ES只能称为准实时的搜索引擎。 写索引流程 数据被写入时,并没有间接写到磁盘,而是被临时写到内存中,默认是1秒,或当内存中的数据量达到肯定阶段,再批量提交到磁盘中。通过提早写策略能够晋升整体写入性能。在达到触发条件后,会将内存中缓存的数据一次性写入磁盘,并生成提交点。清空内存,期待新的数据写入。须要留神的是,正因为有提早写,如果呈现断电等状况会呈现失落数据,为此ES不回了事务日志,来保障事务平安。 段合并策略每次新增数据时都会新增一个段,所以工夫长了后会导致索引中存在大量的段,这样会重大耗费服务资源,也会影响逵性能。咱们晓得索引检索的过程是:查问所有段中满足查问条件的数据,而后对每个段里查问后果集进行合并,所以为了管制索引里段的数量,咱们须要定期进行段合并操作。Lucene合并段的思路是:依据段的大小将段分组,再将属于同一组的段进行合并。因为对那些特地大的段进行合并须要耗费更多的资源,所以Lucene会在段的大小达到肯定规模或段外面的数据达到肯定条数时,不会再进行合并。 类似度打分Lucene的查问过程是:首先在词典中查找每个Term,依据Term取得每个Term所存在的文档链表,而后依据查问条件对链表做交,并,差等操作,链表合并后的后果就是咱们须要查找的数据。然而,咱们一次查问出很多数据时,这些数据和咱们的查问条件又有多大关系呢?其文本类似度是多少呢?它们是在similarity模块实现的。Lucene最经典的两文本类似度算法:基于向量空间模型的算法和基于概率的算法。。。前面的内容看不太懂了就写到这里,有趣味能够看原文。

February 15, 2022 · 1 min · jiezi

关于lucene:基于Lucene实现万亿级多维检索与实时分析

5月29日,录信数软技术总监郑其华在QCon寰球软件开发者大会分享了“基于Lucene实现万亿级多维检索与实时剖析”的主题演讲,现场座无虚席,流动在浓烈的技术探讨气氛中圆满结束。上面,咱们将分享演讲全文。 1.万亿挑战之一:数据存储第一个对于数据存储。平时咱们保留数据很简略,往硬盘外面写就行了。海量数据就没那么简略,会面临很多问题。比方老本问题。是应用SSD固态硬盘还是机械磁盘,是应用100块大磁盘,还是应用1万块小磁盘,在老本上都会造成微小的差别。 其次,数据的安全性也是一个问题。万一磁盘损坏了,或者误删除了,数据就会失落。数据迁徙、扩容也会比拟麻烦。另外,还有一个读写平衡的问题。数据写入不平衡的话,可能就会导致有的磁盘特地忙,有的磁盘很闲暇。或者,如果有个别磁盘出问题了,读写速度变慢了,就会导致所有的查问都会卡在这个磁盘的IO下面,升高了整体性能。 针对存储的这些问题,咱们采纳了基于HDFS的索引技术来解决。 采纳HDFS能够解决哪些问题呢?对于读写不平衡的问题,HDFS是一个高度容错的零碎,如果有磁盘坏掉了,或者速度变慢了,会主动切换到速度较快的正本上进行读取。并且,会对磁盘数据读写进行主动平衡,避免出现数据歪斜的问题。对于数据安全性的问题,HDFS有数据快照、冗余正本等性能,能够升高因磁盘损坏,或者误删除操作带来的数据失落问题。对于存储老本问题,HDFS反对异构存储,能够混合应用各种存储介质,升高硬件老本。而且,HDFS能够反对大规模的集群,应用和治理老本都比拟低。 除此之外,为了进一步升高存储老本,咱们研发了列簇的性能。原生Lucene是不反对列簇的,列簇的益处是什么呢? 咱们能够将数据列,指定为不同的列簇,按列簇来混合应用不同磁盘,并且能够对不同列簇设置不同的生命周期。比方,一个文档外面可能蕴含一些结构化的数据,像题目、作者、摘要等等,这些数据个别比拟小,而且是常常要进行检索的。那么咱们就能够将这些数据列定义为一个列簇,放在SSD上。还有一些相似附件、图片、视频等非结构化的数据,这些数据比拟大,而且个别不会进行查问的,能够定义为另一个列簇,放在的SATA盘下面。从而升高了SSD固态硬盘的使用量。另外,列簇联合HDFS的异构策略,咱们还能够实现冷热数据的拆散。比方,有的业务常常查问最近1个月以内数据。那么,咱们就能够将最近1个月保留在SSD上,1个月当前,将数据,移到SATA盘上,从而进一步升高SSD使用量。 接下来,再看另外一个问题。大数据有一个根本的利用,就是查问检索。比方这个页面上显示的一个“全文检索”性能,是从海量数据外面查找蕴含用户输出关键字的数据。这样的搜寻性能很常见,也不难实现。难的中央在于性能。对于万亿规模的数据,是几秒就响应了,还是几个小时再响应呢? 2.万亿挑战之二,检索性能为了实现万亿秒查的性能。咱们对Lucene的倒排表进行了优化。 在全文检索畛域外面,通常的做法,就是进行切词,而后记录这个关键词在哪个文档外面呈现过。同时,也会保留其余一些相干的信息。比方,这个关键词呈现的频率、在这个文档呈现的地位等等,大略有十几个元素,这些元素就是保留在倒排表外面。Lucene对这些元素,采纳的是行存储。这就意味着,每次查问都须要把所有的十几个元素都读取进去。而咱们在检索时,理论用到的可能只有其中的两三个元素。应用行存的话,会造成很多不必要的IO。因而,咱们在这里,将倒排表外面的元数据,改成了列存储。 列存的益处是,查问用到哪个元素,我只读取这个元素的内容,其余的内容就能够间接跳过。这个改变看上去很小,然而在海量数据的场景,对性能的影响却是极大的。比方,咱们查问的关键字,可能命中了几亿条数据。就须要读取几亿个倒排表的元数据信息,如果应用行存,读取的数据量就是几亿个元数据乘以十几个元素。而列存储的话,只须要读取两三个元素,磁盘IO上就差了好几倍。所以,通过倒排表元数据的列存化,缩小有效IO,这样一个优化,带来了好几倍的性能晋升。 而后,第二个优化的中央呢,咱们将倒排表按时序进行了存储。 因为咱们在理论场景中发现,很多数据会有一个时序性的特点。也就是数据都是随着时间推移而产生的。对这些数据查问时,个别也会联合工夫范畴进行。比方查问最近一天或者最近几小时的汽车尾气排放量等等。而原生Lucene的索引数据在寄存时,是杂乱无序的。同一天的数据,可能存在磁盘的不同地位。这样在读取的时候,就是一个随机读取。所以,咱们在这里也做了一点改良。把数据依照入库的程序进行寄存。那么,咱们在查问某时间段的数据时,只须要将磁盘上这一整块的数据读取进去。咱们晓得机械硬磁盘的随机读取性能比间断读取性能要差很多。而且,磁盘在读取间断数据时还有预读性能。同样大小的数据量,间断读取的性能可能会比随机读取的性能高一个数量级。 通过对索引的优化,基本上万亿数据的检索性能能够做到秒级响应。 3.万亿挑战之三,多维统计接下来看,另一个常见的利用。就是统计分析。 这是一个典型的数据立方体。会波及到多个维度,有工夫维度、地区维度等等。每个维度可能还会有层级关系,比如说咱们先查问每年的汽车保有量数据,而后须要在工夫维度下钻到每个季度的数据,或者到每个月的数据。而原生Lucene在索引上,只有单层的关系,对于一个列,只能建单列的索引,所以在做多维或者多层次的检索统计上,性能会比拟差。 对于多维统计,业界通常的做法,是应用DocValues进行统计分析。而DocValues会带来随机IO的问题。所以,咱们将Lucene的倒排索引表,又进行了批改。这次批改的倒排表外面的term。 原来term外面只能存一个列,改良后,就能够存多个列的值。比方,第一列保留年份、第二列保留季度,第三列保留月份。通过干涉数据的排序散布,在同一个年份,比方2018年下,每个季度的数据都是间断的。这样,在统计分析2018年的每个月的数据时,只须要找到2018年的开始地位,间接读取接下来的一块数据就能够了。 另外,在这个多列联结索引的根底上,咱们还减少了两级跳跃表。每个跳跃表外面会保留多列联结索引的最大最小值。目标是在检索时,能够疾速定位到指定的关键字下面。从而进步单列或者多列的统计分析性能。 4.万亿挑战之四,区域检索而后,咱们再看一个比拟非凡的利用场景——区域检索。区域检索是基于地理位置信息,个别是经纬度进行查问匹配。常见于公安安防行业。 区域检索会有什么样的问题呢?原生Lucene在解决区域检索时,个别是采纳GeoHash来抉择一个正方形,而后应用DocValues进行二次验证。比方,要检索圆形区域的话,就须要裁剪掉多余的几个角。而应用DocValues,跟后面的统计分析一样,就会导致随机读取问题,性能比拟差。 咱们所做的改变呢,就是把原来随机散落在磁盘各个地位的DocValues,改为按地位邻近存储起来。也就是雷同的地理位置的数据,存储的时候,在磁盘上也是挨在一起的。搜寻的时候,因为数据挨在一起,读取就变为一个程序读取。相比原来的随机读取,性能有了一个大幅的晋升。 5.万亿挑战之五,计算框架除了对于存储层和索引层的优化,对于下层的计算框架,咱们也进行了相应的批改。尽管spark作为通用计算引擎,性能上根本满足咱们的需要。然而在万亿数据规模下,依然存在一些问题。例如,spark底层对数据的获取是一条条暴力读取。当数据规模超过万亿时,性能比拟差。想晋升性能,则须要减少硬件投入,老本比拟高。而且在理论生产利用中呈现过各种问题。 所以,咱们对spark进行了批改。将底层的数据存储改为基于咱们自研的分布式索引。Spark在查问的时候,就不须要对数据进行暴力扫描,而是先通过索引,疾速定位到命中的局部数据。从而晋升了数据的查问、统计工夫。同时,咱们修改了大量开源spark的问题,确保在生产零碎中能够稳固运行。 6.产品架构通过上述各个组件的整合和优化,最终咱们造成了如下的产品架构。 底部是Hadoop的根底服务,下面是SQL计算层,通过SQL语句与应用层进行交互。最外围的是两头的存储引擎层,蕴含了lucene的全文检索性能,HBase的KV模型,还有多列联结索引实现的OLAP剖析引擎等。后续还能够在这一层外面进行扩大,实现图数据库以及一些行业定制的性能。 另外,能够通过ETL工具,与常见的内部数据源进行数据导入导出。 7.利用场景这样一套零碎,能够利用在哪些场景呢?能够反对万亿数据的检索剖析吗? 答案是必定的。这个零碎咱们在公安军队行业曾经有很多理论我的项目。公安行业,会集了全网各种维度的数据,超过万亿规模的我的项目十分常见。能够利用这个零碎,通过实时检索、关联碰撞等性能,提供智能研判关系网络,助力公安侦破各种案件。 另外一个场景,就是汽车行业。随着车联网的疾速倒退,汽车产生的数据规模也越来越大。比方,每台车载终端T-Box,每天都会产生数万条数据,几十万台车辆每年产生的数据量就会超过万亿规模。针对国六规范的推广,对车辆的尾气数据、油耗数据都须要进行监管。咱们与中汽研单干,提供的数据存储和检索剖析解决方案,目前曾经利用于各大主机厂。 还有一个咱们最近正在开发和钻研的场景,就是针对于航空和船舶的时空轨迹剖析。通过对于大量的航空和船舶数据进行多维检索和可视化剖析,借助于咱们产品对于工夫、空间数据的优化,从而实现对于类似轨迹的碰撞剖析、随同剖析等。 下面这几个场景的数据量都达到了万亿规模,从理论应用成果来看,咱们这种架构架是能够满足撑持万亿数据的检索剖析需要。 在完结了北京的流动之后,咱们将会在7月23日-24日在深圳大中华喜来登酒店的ArchSummit寰球架构师峰会带来全新的分享,目前议题还 没编出来 在构思中,敬请期待! 下一站,咱们深圳见!

June 2, 2021 · 1 min · jiezi

关于lucene:活动预告‖基于Lucene实现万亿级多维检索与实时分析的实践之路

— QCon寰球软件开发大会(北京) — Lucene是业界最罕用的搜素引擎,咱们所熟知的solr和elasticsearch都是基于Lucene所实现。然而随着数据体量的一直减少,当处于万亿数据的场景之下,所有的惯例操作都会面临海量数据带来的微小压力,如何在保留Lucene高效的全文检索能力的状况下应答万亿数据的挑战,同时突破大数据技术栈各组件性能繁多,适配简单的问题。针对于此,咱们将会在本次QCon寰球软件开发大会上分享咱们这些年在实现基于Lucene的万亿数据挑战中所遇到的问题和解决方案。 01 讲师介绍 郑其华 录信数软 技术总监 原FNST(富士通南大)资深工程师,富士通零碎监督中间件产品项目经理,10年以上软件开发与保护教训 富士通中间件Lifecycle Management和Job Management认证专家 曾负责华为RTOS(实时嵌入式操作系统)的保护,对Linux内核、零碎监督等方面有丰盛教训 中汽研《2020汽车企业数字化研讨会》受邀演讲嘉宾 02 内容预报万亿数据的挑战与实现万亿挑战之一:数据存储如何解决读写不平衡问题,让磁盘盲目分工,实现主动平衡? 如何解决数据安全问题,防止磁盘损坏、误删失落对于生产的影响? 如何解决数据存储老本过高,适度依赖于SSD盘的硬件困局? 万亿挑战之二,检索性能如何实现在万亿数据的全文检索中的秒级响应? 万亿挑战之三,多维统计如何升高IO耗费,实现百万条数据霎时导出? 万亿挑战之四,区域检索如何晋升地理位置检索能力,晋升地理位置检索的精确性? 万亿挑战之五,计算框架如何晋升Spark性能从而大幅提高零碎的响应工夫? 5月29日,咱们北京见!

May 27, 2021 · 1 min · jiezi

关于lucene:关于-ES-的文件格式qbit

前言本文对 Elasticsearch 7.10 实用Elasticsearch 7.10 对应 Lucene 8.7Lucene 8.7 对于扩展名的官网文档 https://lucene.apache.org/cor... 一一解释segments_NName: Segments FileBrief Description: Stores information about a commit pointwrite.lockName: Lock FileBrief Description: The Write lock prevents multiple IndexWriters from writing to the same file..siName: Segment InfoBrief Description: Stores metadata about a segment.cfs, .cfeName: Compound FileBrief Description: An optional "virtual" file consisting of all the other index files for systems that frequently run out of file handles..fnmName: FieldsBrief Description: Stores information about the fieldsfield 数据元信息.fdxName: Field IndexBrief Description: Contains pointers to field data.fdtName: Field DataBrief Description: The stored fields for documents.timName: Term DictionaryBrief Description: The term dictionary, stores term info倒排表指针.tipName: Term IndexBrief Description: The index into the Term Dictionary词典索引.docName: FrequenciesBrief Description: Contains the list of docs which contain each term along with frequency蕴含 term 和频率的文档列表.posName: PositionsBrief Description: Stores position information about where a term occurs in the index.payName: PayloadsBrief Description: Stores additional per-position metadata information such as character offsets and user payloads.nvd, .nvmName: NormsBrief Description: Encodes length and boost factors for docs and fields.dvd, .dvmName: Per-Document ValuesBrief Description: Encodes additional scoring factors or other per-document information..tvxName: Term Vector IndexBrief Description: Stores offset into the document data file.tvdName: Term Vector DataBrief Description: Contains term vector data..livName: Live DocumentsBrief Description: Info about what documents are live.dii, .dimName: Point valuesBrief Description: Holds indexed points, if any本文出自 qbit snap

February 4, 2021 · 2 min · jiezi

大数据时代浅谈医疗数据分析在医疗领域的运用

随着医疗卫生信息化迅速发展 医学研究正步入大数据时代 大数据的许多承诺正在医疗行业变成现实 大数据的实时处理和数据分析 可以让医疗领域的从业者 更快更全面的做出决策和行动 该领域正在慢慢成熟 随着云计算、物联网、移动互联网等新技术水平的提高,各行各业所累计的数据已经呈现指数级的增长。“大数据” 时代已经出现。 近年来,大数据解决方案与大数据分析工具开始被广泛运用于医疗卫生领域。通过数据,可以把医学专家积累的宝贵经验,转化成标准化的知识基础,做到数据驱动医疗服务,因此从而大大提高服务能力和效率,解决中国医疗领域存在的诸多需求。然而健康医疗大数据究竟指的是何种数据?其“大”又体现在何处? 一.大数据 大数据的类型大致可以分为以下两种: 第一种类型是通过对海量数据进行分析,获得巨大价值的产品、服务和见解,我们称之为“动词定义”。 第二种类型是基于多源异构、跨域关联的海量数据(数据量、数据形态、数据分析处理方式),通过分析所产生的决策流程、商业模式、科学范式、生活方式和观念形态上的颠覆性变化的总和,我们称之为“名词定义”。 二.医疗数据 医生对患者诊疗和治疗过程中产生的数据,包括患者的基本数据、电子病历、诊疗数据、医学影像数据、医学管理、经济数据、医疗设备和仪器数据等,以患者为中心,成为医疗数据的主要来源。 三.医疗数据来源 首先来讲,“医疗数据”的主要来源有四个方面,第一种是患者就医,第二种是临床研究和科研,第三种是生命制药,第四种是可穿戴设备。 第一种“患者就医”,源于患者,患者的体征数据、患者的化验数据、患者的描述,患者的住院数据、医生对患者的问诊数据、医生对患者的临床诊治、用药、手术等数据。 第二种“临床研究和科研”主要是实验中产生的数据,也包含患者产生的数据。 第三种“生命制药”主要是实验产生的数据,与用药相关的用药量,用药时间,用药成分,实验对象反应时间,症状改善表象等数据,与生命等基因组学相关的数据。 第四种“可穿戴设备”主要通过各种穿戴设备(手环、起搏器、眼镜等)收集人体的各种体征数据。 四.医疗数据特性 医疗数据首先它属于数据的一种,所以其大数据也必定具备一般的数据特性:规模大、结构多样、增长快速、价值巨大,但是其作为医疗领域产生的数据也同样具备医疗性:多态性、不完整性、冗余性、时间性、隐私性。 多态性:医疗数据包含有像化验产生的纯数据,也会有像体检产生的图像数据类似心电图等信号图谱,医生对患者的症状描述以及跟进自己经验或者数据结果做出的判断等文字描述,另外还有像心跳声,哭声,咳嗽声等类似的声音资料,同时现代医院的数据中还有各种动画数据(像胎动的影像等)。 不完整性:由于各种原因导致有很多医学数据是不完整的,像医生的主观判断以及文字描述的不完整,患者治疗中断导致的数据不完整,患者描述不清导致的数据不完整等。 冗余性:医疗数据量巨大,每天会产生大量多余的数据,这给数据分析的筛选带来了很大困难。 时间性:大多医疗数据都是具有时间性、持续性的,像心电图,胎动思维图均属于时间维度内的数据变化图谱。 隐私性:隐私性也是医疗数据的一个重要特性,同时也是现在大部分医疗数据不愿对外开放的一个原因,很多医院的临床数据系统都是相对独立的局域网络,甚至不会去对外联网。 五、数据的处理 数据的处理一般分为6个步骤:挖掘数据、收集数据、分析数据、存储数据、数据转化实用,最终在实用过程中产生数据,如此循环。 六.医疗大数据的用途 医疗大数据的主要用途有:用药分析、病因分析、移动医疗、基因组学、疾病预防、可穿戴医疗等。 随着医疗大数据的发展和分析方法、人工智能等技术的不断革新,能够准确利用医疗大数据来进行分析和预测的场景会越来越多,到时大数据将会成为医疗决策的一种重要辅助依据。 七.医疗大数据 医疗大数据企业主要分为三类:慢病及健康管理(辅助患者)、临床决策支持(辅助医生)、医药研发。 医疗大数据的服务对象主要有:居民、医生、科研、管理机构、公众健康。 医疗大数据的主要用途有:用药分析、病因分析、移动医疗、基因组学、疾病预防、可穿戴医疗等。 八.统计学在医疗方面的运用 统计学是医学科学研究的重要工具,运用概率论与数理统计的原理及方法,结合医学实际,研究数字资料的搜集、整进行理分析与推断。正确的统计分析能够帮助人们正确认识客观事物的规律性,做到胸中有数,有的放矢地开展工作,提高工作质量。 在统计分析领域中,有一种用途极其广泛的特征曲线,叫做接受者操作特性曲线。 得此名的原因在于曲线上各点反映着相同的感受性,它们都是对同一信号刺激的反应,只不过是在几种不同的判定标准下所得的结果而已。 接受者操作特性曲线就是以虚惊概率为横轴,击中概率为纵轴所组成的坐标图,和被试在特定刺激条件下由于采用不同的判断标准得出的不同结果画出的曲线。 在统计学中常讲到的AUC就是”Area Under the ROC curve“,它的值是介于0.1到1之间,是当前分类算法根据计算所得的一个score值,AUC值越大说明正样本越有可能排在负样本之前,从而能更好进行统计样本的分类。 在现有的一个统计学方法中,我们对样本的诊断通常是分为两类,一个是健康类,另一类是得病类。除了这两类以外,还存在一种人群叫亚健康人群,如果我们还是按照原有的方法去给病人进行分类的话,那么我们所得到的一些结果可能是具有误导性的。 在统计学中概率样本的置信区间是对样本的某个总体参数的区间,估计通常来说,比如说我们说有95%的置信区间,那么就是说测试者有95%的统计量是落在置信区间内的。 它其实展示了这个参数的真实值,有一定概率落在测试结果周围的一个程度,也给出被测量参数测试测量值的一个可信程度。 怎么去判断这个诊断的一个精确性,我们需要看的是置信区间的一个覆盖率,如果这个覆盖率越接近于既定的一个概率的话,那么这个方法就越精确。 广泛搜寻,就是把所有的值结合在一起,然后去比较它们之间的大小,用这种比对的方法来找出最大的不同。 如此可见,随着医疗服务提供者越来越善于从患者数据中提取有意义的见解,他们也将学习更好的提供治疗的方法,提高服务质量。随着大数据技术领域的成熟,许多组织将受益于运营的改善、费用的降低和健康状况的改善。 通过许多方式,大数据和人工智能可以帮助解决日益严重的护理提供者短缺问题。医疗服务提供商也将充分利用大数据技术为医疗技术框架持续提供动力。

June 25, 2019 · 1 min · jiezi

别让任何人打乱你的节奏

《别让任何人打乱你的生活节奏》完美人生 就是 18岁成人 22岁大学毕业,25岁工作稳定,30岁之前买房结婚生子,35岁之后人生轨迹就会定型…… 可是每一个时间段表里都有必须完成的任务 那,我们没有其他的活法了吗? 正如从一分多开始的另一个人演讲: 有的人在16岁就清楚知道自己要什么,但在26岁时改变了想法; 有的人有了孩子,却还是单身; 有的人结了婚,却等了10年才生孩子; 有的人身处一段感情,爱的却是别人; 有的人明明彼此相爱,却没有在一起。 人生中的每一件事都取决于我们自己的时间,你身边有些朋友也许遥遥领先于你,有些朋友也许落后于你,但凡事都有它自己的节奏 因此,无论当下如何,保持一颗平静的心,从容对待。你想要的,终究会来。 就像,姜子牙80岁才挂帅,司马懿60多岁才受到重用,刘备40多岁才有自己的队伍。所以,一切都不晚,该来的总会来。 要知道,人生有时候走得慢一点,稳一点,反而会更快靠近自己想要的生活,有些东西来得晚一点,等得久一点, 往往更珍贵。就像嘉措活佛说的那样:“一切都是最好的安排”。命运的安排一切都很精准;路是脚踏出来的,历史是人写出来的,人的每一步行动都在书写自己的历史。而生命就是在等待正确的行动时机,所以不用嫉妒或嘲笑他们。更不要急着让命运给予你所有的答案,有时候,你总要拿出耐心等一等; 即使你向空谷喊话,也要等一会儿,才会听见那绵长的回音。《楞严经》上说:“若能转物,则同如来。”无论遇到善缘、逆缘,顺境、逆境,只要你肯等一等,生活的美好,总在你不经意时,盛装莅临。最后,在生命的时区里,愿你走出半生,归来仍是少年。愿你始终相信,一切都会准时到来的。 《慢慢来,一切都来得及》 --恋爱观,人生观 梦想,不是说说而已的just do it , anything ls possible (NIKe+LIning) 凡有经过,必有回响----所以你的努力并不是白费的 因为我知道自己每一天都在认真地生活着,因为我正努力一步步朝着梦想迈进,因此每一天过得还算充实和快乐。这样一想我就不再焦虑了。我又问自己,如果给自己两年的时间去学习英语口语,慢慢来,给自己20年的时间去实现梦想,慢慢来,可以吗?答案是可以。我顿时整个人放松下来,当我允许自己慢慢来时,忽然感觉那种轻装上阵,脚踏实地的坚实力量又回到了自己的身上。 有朋友问我,你会一直待在上海吗?我会回答不知道,因为我觉得未来是迷茫的,未来的事情也是难以预料的。我对生活一直怀有很多困惑,我觉得正是这些困惑推动着我不断去思考、去努力、去前进。 你问我不知道自己想要什么,怎么办?我会告诉你,那你赶紧去找啊。在20岁出头的年纪,不知道自己想要什么是一件极其正常的事情,也是一件幸运的事情,因为当你有了困惑之后,你才会思考,才会一步步地寻找自己想要的东西。 如果你真的没有发现自己喜欢的事情,那请不要放过任何尝试的机会,你可以接受各种挑战,尝试去做各种事情,不要拿自己太当回事了,丢弃那虚妄的自尊,不要怕出丑不要怕失败,你甚至要允许自己经常失败,给你面对失败的经验,给自己不断重新再来的勇气,你要做的就是积极地尝试,直到找到自己内心真正的热爱,找到自己愿意为之努力的梦想。要给自己时间,让自己慢慢来,给自己面对失败的勇气和对梦想持续的热情,因为最难的事情不是面对失败,而是面对一而再再而三的失败还能永保热情。 人生从来不是规划出来的,而是一步步走出来的。找到自己喜欢的事情,每天做那么一点点,时间一长,你就会看到自己的成长。 对于很多像我一样缺乏独立思考能力,又不懂得借鉴他人历史教训的人,只有亲身经历过,才能知道自己想要什么样的生活,就算不知道自己到底想要的是怎样的生活,也至少能明白自己不想要怎样的生活。 我一直想不明白,怎么有这么多人这样算计人生呢?人生真的不是算计出来的。有人说:“只有一次的生命,需要活得真性情一点。”真性情就是你不要压抑自己的需求,你要听从自己内心的声音,过自己想要的生活。也许我在念书的时候就结婚生孩子呢?就算念完书,年纪大了再结婚生子又怎样呢?就算我一辈子不结婚生孩子又怎样呢?难道就不会幸福吗?你的生活是需要别人对你说“好”你才会觉得好吗?你的安全感是来自符合社会习俗制定的标准吗?你的幸福感是建立在别人对你的生活投以羡慕嫉妒的目光上的吗?真正的强者是能在人生的旅途中蜕变为只对自己心声负责的达人。 那些早早找到自己的人生梦想,遵循天命的人,固然很幸运;但是,那些还没有找到自己应该走的道路的人也不必感到万分痛苦,因为一切都还来得及,你要给自己慢慢来的机会。我们乡下的老人常常告诫年轻人的一句话:饭要一口口地吃,路要一步步地走。 我常常告诫自己说,想做一件事就要立刻行动起来,不然就跟那些徒有羡慕之情却给自己诸多理由毫无行动的人们一个样。 只有一种英雄主义,就是在认清生活真相之后依然热爱生活 梭罗说:“生命并没有价值,除非你选择并赋予它价值。没有哪一个地方有幸福,除非你为自己带来幸福。” “常有人说我坚持得好,其实真正喜欢的事不用‘坚持’,让自己变得健康,真的很容易,不停地跑下去,就不会老。跑步可以沿途欣赏美景,享受运动的快乐,人生就是一场马拉松,谁健康,谁就能跑得更长远!” “做真正喜欢的事情不用坚持。” 所以,找到自己喜欢的事情非常重要。因为喜欢,你不用苦苦坚持,也因为喜欢,你愿意投入时间、精力,长久以往获得成功就是自然而然的事情。这一点同样适用在寻找爱人这件事上。找到自己真正喜欢的人,与之在一起,并不需要费力坚持,太过辛苦经营,只因为你们在一起是喜欢的、快乐的、充实的。在一起的时间越长,爱情如美酒一般变得愈加醇美。 就像山田本一所说的那样,拆分目标的好处在于:一、使得原本看起来有些吓人的大目标变得容易靠近和比较现实了。当你的心里认定这个目标可以实现时,就不会因为害怕失败而放弃你的行动。人做一件事拖延的原因有很多,其中一个就是把目标定得太高,害怕自己无法实现,其实就是恐惧失败。细化目标可以减少或者避免由于害怕失败而产生的拖延。二、细化目标还可以增加信心。当你觉得目标可以实现时、容易成功时,你就会更有信心。不言而喻的是信心对完成任务的作用很大。 吴淡如在《时间管理幸福学》中说道:“只要想到一件事情可以‘一石二鸟’或‘一石三鸟’我们比较容易有‘赚到’的感觉,会因为自己的‘贪恋’而继续下去。” “为一件事情找到多种目的”在工作和学习中都很适用。 做一件事情时,加强它的正面意义,为它多找一些其他目的,不仅能让你快乐地完成这件事,还让你的生活变得积极而高效,充满正能量。 下雨天的时候,一下班我就匆匆回家,刚到楼梯口,嘴里就念着:泡面、泡面、荷包蛋、荷包蛋……(我是个多容易满足的正牌吃货啊)然后“咔嚓”一声开门,蹬掉高跟鞋,用平底锅煮泡面吃,就着外面的雨声,吃着热气腾腾的荷包蛋泡面。下雨的夜晚,抱着锅,吃着泡面,我会感觉很幸福呢! 孤独要趁好时光。趁着好时光,独自欣赏月升日落,独自面对生活的波澜起伏。孤独是人生的重要伴侣,学会独处,乐在独处的人也许过得才最自由自在。越来越觉得人的一生归根结底是与自己相处,与自己斗争的过程,要与自己的万千情绪相处,与自己的各种欲望斗争,与自己的软弱、惰性、劣势不停地斗争下去,爱恨情仇,贪嗔痴慢全是你自己一个人的。 上周和许久未见的一个朋友见面,他说我变得自信了。我明白我的自信不是来自薪水的增加、消费能力的提高或者工作能力的增强,而是来源于相信自己有进一步完善自己、改变自己的能力,同时能看到自己的局限,做得到改变能够改变的,接受不能改变的;相信自己有爱自己、爱他人的能力;相信自己一个人生活也过得好。 以前我一直在逃离生活,与生活保持着一定的距离,觉得走到哪里,怎样的生活都不是自己想要的。这两年我感觉自己渐渐脚踏实地了,开始贴着生活在好好地过日子,虽然做得还不够好,但是一直在进步。蓦然回首,我一个人走过了那么多时光,也走了很远,从乡村到都市,从荒凉到繁华,从深夜到清晨,从弱小到强大,从艰难到轻松,从痛苦到狂喜,所有的这些我都一个人一一走过,虽然我走得慢,但是我走得很认真很努力,从没有因为害怕而停止。 通过观察和经验,我发现那些稍微准备就去干的人和非要准备充分才去行动的人最大的区别就在于对人生的认知不同。前者认为人生是各种体验的集合,后者认为人生是各种成功的档案。因此前者往往充满活力和冒险精神,充满勇气和自信。注重过程,乐于接受变化和挑战,不惧怕失败,情绪乐观,面对失败也较轻松和正面,觉得至少能收获一份经验。这样的人常常大胆尝试,敢于打破规则,愿意去做许多未知的事情;后者则畏首畏尾,缺乏勇气和自信,全然以目标为导向。害怕变化和挑战,也非常害怕失败,只要一失败简直会要了他的命,压力沉重,甚至陷入无法自拔的沮丧和毁灭之中,这样的人因为很多的不敢为,所以经历的事情也比较少,囿于自身思维中的各种限制,躲在自己认为的安全区中。 李欣频说:“当你匮乏时不会有人把资源给你,只有当你真正丰富了才会给你。”当你真正做到踏踏实实地完善自己、丰富自己,专心做可以提升自己的事情,学习并拥有更高的技能的时候,很多机会就会降临到你身上。 你经受的每一份痛苦都是上天赐予你的一份神秘礼物(其实能这样想还真不容易),我希望你能从所受的每一份痛苦中获得学习、累积和成长。如果你经历的痛苦仅仅是痛苦,无法将痛苦转换成人生的养分,去灌注自己内心的坚强之花,那么你也许一辈子都痛苦脆弱,与坚强无缘,也找不到自己的存在感。 我一边心不甘情不愿地写着方案,一边想到后面还有那么多工作要做,想着明天就要提交工作成果了。重压、愤怒、怨恨、控诉、敌意和挫败等负面情绪一股脑地冲向我,我崩溃了,居然呜呜地哭了起来。意识到眼泪正夺眶而出,我被自己“正在哭”这一事实吓坏了,这虽然不是我第一次因为工作压力大而哭泣,但那是前两年的事情了,现在我毕竟是工作了三年的职场之人,怎么就这样脆弱,不堪一击?这时心中有一个声音响起:“哭能解决问题吗?难道有人逼你这样做吗?现在这个局面是谁造成的?你打算怎么办?” 趋利避害,逃避责任,这是每一个人都会有的正常心理,但是这并不代表它是好东西,相反,这正是导致许多人生活不幸的原因。 是的,我们需要停止抱怨,抱怨只会带来坏处,一点正面积极的好处都没有的,它会分散你的注意力,消耗你的精力,瓦解你的信心,摧毁你的行动力。抱怨还会限制我们思考,阻挡我们有效工作。因为,当我们抱怨的时候就把焦点放在我们不想要的东西上,所谈论的是负面的、出错的事情,而我们把注意力放在什么上头,那个东西就会扩大。我们抱怨的言语会影响我们的思维,进而影响我们的想法和态度,从而给我们的生活带来负面的影响。同时抱怨还会影响我们的人际关系。试想一下,谁愿意跟一个成天抱怨的人在一起共事呢? Bronnie Ware专门照顾那些临终病人,听到很多人临终前说出他们一生里最后悔的事。她作了一个概括,有5件事是大多数人最后悔的。 我希望当初我有勇气过自己真正想要的生活,而不是别人希望我过的生活。 2. 我希望当初我没有花这么多精力在工作上。 3. 我希望当初我能有勇气表达我的感受。 4. 我希望当初我能和朋友保持联系。 5. 我希望当初我能让自己活得开心点。亲自听闻了1000多例病患的临终遗言后,他写下了这本书,其中排在前五位的是: ...

June 19, 2019 · 1 min · jiezi

elasticsearch入坑到理解

为什么要用elasticsearch随着你工作年限的增长,获得到的信息也越来越多。终于有一天你认识了elasticsearch。但是你真的知道为什么你的系统需要用es么?什么是搜索?百度:我们比如说想找寻任何的信息的时候,就会上百度去搜索一下,比如说找一部自己喜欢的电影,或者说找一本喜欢的书,或者找一条感兴趣的新闻(提到搜索的第一印象)垂直搜索(站内搜索)互联网的搜索:电商网站,招聘网站,新闻网站,各种appIT系统的搜索:OA软件,办公自动化软件,会议管理,日程管理,项目管理,员工管理,搜索“张三”,“张三儿”,“张小三”;有个电商网站,卖家,后台管理系统,搜索“牙膏”,订单,“牙膏相关的订单”搜索,就是在任何场景下,找寻你想要的信息,这个时候,会输入一段你要搜索的关键字,然后就期望找到这个关键字相关的有些信息如果用数据库做搜索会怎么样?做软件开发的话,或者对IT、计算机有一定的了解的话,都知道,数据都是存储在数据库里面的,比如说电商网站的商品信息,招聘网站的职位信息,新闻网站的新闻信息,等等吧。所以说,很自然的一点,如果说从技术的角度去考虑,如何实现如说,电商网站内部的搜索功能的话,就可以考虑,去使用数据库去进行搜索。1.比方说,每条记录的指定字段的文本,可能会很长,比如说“商品描述”字段的长度,有长达数千个,甚至数万个字符,这个时候,每次都要对每条记录的所有文本进行扫描,来判断说,你包不包含我指定的这个关键词(比如说“牙膏”)2.还不能将搜索词拆分开来,尽可能去搜索更多的符合你的期望的结果,比如输入“生化机”,就搜索不出来“生化危机”es如何处理

March 16, 2019 · 1 min · jiezi

第三天

今天早上复习了前两天看的Linux;上午四节课 ,算法、Javaee;中午把上午Javaee的作业写好了;下午物联网两节课,上完学车去了,到六点钟回到自习室。开始写算法题,到20:56回去洗漱睡觉。

March 13, 2019 · 1 min · jiezi

第二天

早上上课,学习了算法 ,主要讲了递归,物联网课上看了Linux;下午练车,晚上五点钟回来,吃完饭到自习室看书 ,看Linux到20:30;下自习回去了 ;回去就不开电脑;今天记录结束。

March 12, 2019 · 1 min · jiezi

一种自动化的信息管理构建系统

此文首发于知乎Talk is cheap, show me the code.手里有码,心中不慌。源码敬上 ihongs/HongsCORE按照一篇技术文章的惯例,先得定义名词、作出解释:信息管理系统:信息管理系统_百度百科,往大了说,除了图书管理、仓储管理,电商、资讯网站和大部分的 APP 后台都属于信息管理系统。但此文并不讨论复杂的系统,只浅涉一点点基础的,也不牵扯到 OLTP/OLAP 之类概念,只讨论一个玩笑般的话题:增删改查。自动化构建:我认为全自动的构建方式就是人向机器提出需求,机器直接给出完整方案,过程中机器可能会询问并等你作出抉择,但无需程序员干预细节;相对的,半自动化仍然需要人来确定枝枝蔓蔓的细节,但具体的数据流转逻辑无需编写代码。不过,这不是论文,这不是论文,这不是论文!从上述定义来说,本文谈到的系统只能算"近半自动化",当超脱那些简单但繁琐的基础逻辑后,仍然需要程序员去干预甚至覆盖重建。我试图让这个系统不是一个秤砣啃不动砸不烂,好让其可干预、可拆散、可重建。这不会生成逻辑代码,只会产生结构类代码,如果需要,可以过滤输入输出和覆盖重写逻辑,但不存在“修改”逻辑代码这么个操作,因为没有逻辑程序代码产生——没有这个必要。数据与逻辑并不是天然分隔的,一个程序代码之所以成为逻辑指令,只有当被执行的时候才表现出来那些动态的判断和分支,但当它存储在硬盘里,不管里面写了多少动词,是文本还是二进制,他跟一篇文章或一个图片没有本质上的区别。所以,编程面对的就是把上游数据进行合理的解释,从一个数据结构转换成另一个数据结构,这个转换过程一般情况下由人来完成——码农就是这个转换的解释器。说到转换,我就想到我们师徒四人换取通关文牒……抱歉抱歉,走错片场了。举个例子,现在有个文牒、哦不、文档查询网站,首页提供了一个搜索框,上面有关键词、分类和标签三项,当您输入关键词、选择分类和标签后点击搜索,页面会向服务器重新请求并跳转,URL 从 http://xxx.com/document 变成 http://xxx.com/document?word=催化&type=化工&tags[]=高新科技&tags[]=前沿技术,到服务器后,尾巴上的参数转换成 {word: “催化”, type: “化工”, tags: [“高新科技”, “前沿技术”]},再被转换成 SQL 查询语句 SELECT * FROM document WHERE word LIKE ‘%催化%’ AND type = ‘化工’ AND tags IN (‘高新科技’,‘前沿技术’)。从 URL 的问号后的查询串转换为程序里的结构化数据,这个过程一般由服务容器或应用框架自动完成,这个过程是一对一的映射,基本不存在歧义,所以往往不用程序员手工编程处理;但是从请求数据转换成查询语句,就不太好”通用“了。type=化工 和 word=催化 有什么区别吗?都是一个等于号挑着两个串,谁知道前者对应的是 = 而后者就要变成 LIKE 呢?答案是程序员知道,因为产品经理让他这么干的。他会写代码:if (request.word) sql += " AND word LIKE {request.word}",这只是用伪代码举例,不用纠结看不看得懂,现实中出于分层、通用、规范甚至是装逼,可能在数据与查询之间再用一个额外的框架,框架又采用一种中间数据结构,然后由框架再转成实际的查询。可以想象,程序员脑子里装了一份底板,如果产品经理说什么需求那么他就会写什么代码?把前面这个”如果“拿掉,就可以用一个映射来描述 需求=>代码。当一个老码农阅码无数后找出来几种常用转换归类,那么,可以用结构化的方式描述底板:{ “一般字段”: “{字段名} = ‘{取值}’”, “关键词类”: “{字段名} LIKE ‘%{取值}%’”, “多个值类”: “{字段名} IN (JOIN(’,’,{取值}))"}如果进一步发掘共同点,还能总结出数字类型、日期类型,然后前端表单结构那边让一步,双方约定好规则,比如加 _lt 后缀的表示小于、加 _gt 后缀的表示大于,或是在值的格式上做文章,定义为类似数学区间的形式 (min,max) [min,max]。这还不够,结构描述我们还可以搬进去更多东西,比如 docuemnt 表跟 author 表之间什么关系。说到关系……串场了串场了……对于关系,可以查阅 ERM (实体关系模型) 相关的资料,并不需要技术背景就能看明白。简单来说,我们可以将文档(资源、实体)之间的关系归纳为一对一、一对多、多对多,加上依赖方向,再衍生出几种不同的图例。反过去向下追究,到物理模型,就只有一种关系,可以用 UML 的类图表示为依赖,只需要一个箭头符号来指向被依赖方。好久不画了、软件也没装,度娘搜来的 ERM 图例和 UML 类图太丑,略起初,我的系统建立在关系数据库之上,这也是常见的教科书式的手段。数据库的表结构本身含有一定的描述,比如字段名、字段类型、取值约束等。但这显然还不够,于是定义了一个 xml 来描述表和表之间的关系;这部分其实也能从数据库本身取得,但获取方式在各数据库产商中并不像 SQL 那样有一致的规范,而想要统一就得进行封装,内部再来处理差异部分。这偏离了目标,因此仅在完成 MySQL 的结构提取后就终止了,改为自行描述关联关系。这样做顺便得到一个好处,很多时候可以不需要 JOIN 就能完成关联查询,甚至跨库跨数据库类型的关联的——尽管可能效率不够高。这个关系数据库的描述文件见:默认配置,内部注释含写法;格式描述。https://pic3.zhimg.com/v2-98d…用户模块的关系描述文件后来,NoSQL 兴起,有 Redis、MongoDB、CouchDB 等诸多选择,可惜这一次这些大厂似乎谁也没说服谁,无法形成统一的标准。如果定义一个资源对象就是一个文档(参考简历的结构),因此选择文档类数据库就再合适不过了。Redis 等键值库肯定不行了,弃之;我还希望这个库能嵌入我的系统,这样就可以像 Sqlite 那样一同打包、一并启动。于是 Lucene 成了不二的选择。Lucene 非数据库?此话怎讲?阿里搞搜索的人说他们的业务部门希望他们的搜索系统像数据库一样即存即取,印象里他们还专门发文谈到过。坑他们都踩过了,虽不知道如何跳过去的,但只要知道能过去就行了。所以 Lucene 不但是数据库,还是很好的文档数据库;需要的话还可以是图(谱)数据库,Neo4j 底层即为 Lucene,我也有直接用 Lucene 开发过人脉关系引擎。打断一下,现在你要搜 Lucene 首先进入的是 Solr 的站点,Lucene 已经成了 Solr 的一个附件。为什么不选择封装得更完备的 Solr?除了上面说的需要嵌入的原因,还因为将要谈到的描述结构 Solr 就那么干了。大爷我手里有枪,别拿你那大炮仗吓唬人。文档数据库是没有固定结构的,怎么存怎么取你说了算。这很麻烦,但对我的需求来说,这太棒了。就意味着,只要做一个结构生成器,再也不必为如何生成和变更表结构伤脑筋了。先把示例文件甩出来:默认配置,内部注释含写法;结构描述。https://pic3.zhimg.com/v2-be2…自动生成的资源描述文件至此,码农脑子里那份底板已经抠出来最简单但也是最常用的部分了,码农们在这一瞬间得到了解脱。放心,失不了业;搞成平台除外,但也不必担心,真那样的话只会刺激市场释放更多需求,然后码农们搞得风生水起,“升值加薪,当上总经理,赢取白富美”……打住打住,“你有权保持沉默,但是你没权扯淡啊”。然后呢?让产品经理去写配置?倒也是,这 XML 看上去也没比 PRD 难在哪嘛。但送佛还是要送上西天D,拿键盘敲代码(尽管不是逻辑代码)这种蠢事让我们码农干就行了,还是要搞个图形界面好让人指点江山呀。https://pic1.zhimg.com/v2-ed0…资源设置界面https://pic1.zhimg.com/v2-6ff…资源管理界面https://pic1.zhimg.com/v2-655…资源编辑界面https://pic2.zhimg.com/v2-8e0…接口文档界面https://pic1.zhimg.com/v2-758…对外开放界面https://pic2.zhimg.com/v2-ef7…开放查看界面第一幅图的设置完成后,后面的界面就自动产生了。这个依据是什么呢?产品经理、助理们会画出一个个原型图,程序员看了后想象数据该如何存储,然后倒腾脑海里那一堆代码底板,最终变成逻辑和页面。这要说回上十年以前,没有产品经理,没有 UI、UE,几个程序员在白板上比划两下就撸起袖子开干了;至于界面,顶多再拉个美工做几个水晶按钮,现实中相近的东西长什么样,软件就尽量做成什么样。这个话题深入下去可以谈到“自顶而下”和“自底而上”两种设计方式。简单来说,一个是从表面看问题,最后确定一下如何将状态持久化;一个是从底层看问题,先确定数据如何存储然后向上逐层扩展直至界面。实际的情况多是两者相结合的,“自顶而下设计,自底而上实现”。现在穿越时空回到过去,定义有什么样的结构就该有什么的界面,那么从那个表单配置 XML 出发,通过研究历史的界面和操作流程,进行总结并将过程固定下来,形成映射关系,就自然可以产生操作界面了。具体点来说,总结发现一个普通的 UI 流转过程可以抽象为 加载、打开、发送 3 种类型,采用事件驱动,并在流程上规定“谁打开、谁负责”,让各大组件间可以用最通用、最简单方式交换状态。但与面向前端程序员的接口不同,UI 是面向人的,而人的思想和喜好具有很大的不确定性,因此,并未对 UI 部分提供更多的辅助设置。一个注定要被重新编写的东西,你做的越多那么定制的人改起来就越累,一点多余也不做,就是最好的选择。当超越时间去看待问题,一切过程都是结构。TODO:没人愿意看你的代码,这里应当放一个演示视频。谈一个技术上有争议的事,为了实现这个系统,我打造了一个完整的应用框架,完全不同于 Spring,Struts 这些业界流行的产品。参考了 PHP 的松散数据结构,参考了 Spring 的反转控制,参考了 Python Django 的校验模型(有四五年没用了,不知道现在套路变了没)。而且大量使用集合框架,而很少去构造私有结构,这在部分程序员看来可能是过于松散,有些应该做只读隔离的却没有做封装。但熟悉 Java 的都知道,反射其实能跳过很多限制,有些隔离封装就是防君子不防小人。我没有必要对此上工作的程序员像防贼一样时刻惦记着,而只要一个约定即可:有些全局的东西你最好别去变更。不管您认不认同,看在码了这么多年的份上,给我 GayHub 上可怜的星星数 ++再补充一个,知乎上有谈到人工智能生成代码的话题。AI 很火,2018 年火得一塌糊涂,我所在公司的一个兄弟单位也在搞,一下子好像 AI 要统治世界。那么,这里面最让各路人员不爽的当然是码农兄弟们了,让你们做个软件磨磨唧唧的,如果机器能写代码了,那就不需要雇佣程序员了,再也不会跟他们因讨论识别手机壳换主题颜色的问题干仗了。可是,如果某个系统的产出是程序代码,那么他首先的用户不应该是码农吗?如果您的系统是为了解决某些普遍的问题,能生成代码为什么不直接执行解决问题呢?如果需要生成代码,那只有一种可能就是那个生成的代码不够完善没法直接应用于终端,需要码农去微调。一二十年前的一些 UML 工具箱就能生成代码,人类似乎太健忘了。5 年前我还在魔都干着互联网广告的勾当(所以没准几年前您在各网站上瞎点时咱们就产生间接联系了),也写过一个小的报告系统,中间会生成报表代码,原因正是上面说到的,跟各不同报表需求部门扯不清楚,短时间内没法总结出普适的规则,所以生成脚本代码,以便在接到特殊逻辑后快速微调。所以,虽然我认同 AI 的发展方向,并因不能全身进入而为自己的未来感到担忧;但是,我不认同用 AI 生产代码是个好主意。承载代码的是编程语言,而语言就是沟通的桥梁。AI 与 AI 之间可能在未来会产生属于他们自己的沟通规则,但那不应当是适合人类阅读的程序逻辑代码。 ...

January 14, 2019 · 1 min · jiezi