<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>中间件 on 易哥</title>
		<link>https://yeecode.top/tags/%E4%B8%AD%E9%97%B4%E4%BB%B6/</link>
		<description>Recent content in 中间件 on 易哥</description>
		<generator>Hugo</generator>
		<language>zh-cn</language>
		
		
		
		
			<lastBuildDate>Sat, 09 Jan 2021 00:00:00 +0000</lastBuildDate>
		
			<atom:link href="https://yeecode.top/tags/%E4%B8%AD%E9%97%B4%E4%BB%B6/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>全文检索的原理</title>
				<link>https://yeecode.top/blog/46/</link>
				<pubDate>Sat, 09 Jan 2021 00:00:00 +0000</pubDate>
				<guid>https://yeecode.top/blog/46/</guid>
				<description>&lt;p&gt;本文将介绍全文检索的原理，也是Lucene工作原理。而开源的搜索引擎Solr和Elasticsearch也都是基于Lucene实现的。因此本文介绍的原理是以上这些软件的基础。&lt;/p&gt;&#xA;&lt;p&gt;另外，本文并非原创，是参考网络上的资料整理而来，删减了一些冗余的段落、整理了错乱的格式等。本文原始出处难以考证。&lt;/p&gt;&#xA;&lt;h2 id=&#34;1-全文检索概述&#34;&gt;1. 全文检索概述&lt;/h2&gt;&#xA;&lt;p&gt;数据总体分为两种：结构化数据和非结构化数据。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;结构化数据：指具有固定格式或有限长度的数据，如数据库，元数据等。&lt;/li&gt;&#xA;&lt;li&gt;非结构化数据：指不定长或无固定格式的数据，如邮件，word文档等。非结构化数据又一种叫法叫全文数据。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;当然有的地方还会提到第三种，半结构化数据，如XML，HTML等，当根据需要可按结构化数据来处理，也可抽取出纯文本按非结构化数据来处理。&lt;/p&gt;&#xA;&lt;p&gt;按照数据的分类，搜索也分为两种：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;对结构化数据的搜索：如对数据库的搜索，用SQL语句。再如对元数据的搜索，如利用windows搜索对文件名，类型，修改时间进行搜索等。&lt;/li&gt;&#xA;&lt;li&gt;对非结构化数据的搜索：如利用windows的搜索也可以搜索文件内容，Linux下的grep命令，再如用Google和百度可以搜索大量内容数据。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;我们说的全文检索就是对非结构化数据的搜索。主要分为两种方式：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;顺序扫描法(Serial Scanning)：从头到尾对全文数据进行扫描。&lt;/li&gt;&#xA;&lt;li&gt;全文检索(Full-text Search)：先建立索引，然后基于索引进行搜索。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;这里就引出了全文检索。&lt;strong&gt;全文检索是基于索引，对非结构化数据进行的搜索。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;下面一图展现了全文搜索的整体过程。全文检索大体分两个过程，索引创建(Indexing)和搜索索引(Search)。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;索引创建：将现实世界中所有的结构化和非结构化数据提取信息，创建索引的过程。&lt;/li&gt;&#xA;&lt;li&gt;搜索索引：就是得到用户的查询请求，搜索创建的索引，然后返回结果的过程。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://yeecode.top/blog/46/pic/001_hu_89aae74c8d824c63.webp&#34; alt=&#34;全文检索&#34; width=&#34;544&#34; height=&#34;479&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;于是全文检索就存在三个重要问题：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;索引里面究竟存些什么？(Index)&lt;/li&gt;&#xA;&lt;li&gt;如何创建索引？(Indexing)&lt;/li&gt;&#xA;&lt;li&gt;如何对索引进行搜索？(Search)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;下面依次进行介绍。&lt;/p&gt;&#xA;&lt;h2 id=&#34;2-索引里存在什么&#34;&gt;2. 索引里存在什么&lt;/h2&gt;&#xA;&lt;p&gt;假设我的文档集合里面有100篇文档，为了方便表示，我们为文档编号从1到100，得到下面的结构&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://yeecode.top/blog/46/pic/002_hu_83cfbf22a4bdcbff.webp&#34; alt=&#34;图片&#34; width=&#34;544&#34; height=&#34;153&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;左边保存的是一系列字符串，称为词典。&lt;/p&gt;&#xA;&lt;p&gt;每个字符串都指向包含此字符串的文档(Document)链表，此文档链表称为倒排表(Posting List)。&lt;/p&gt;&#xA;&lt;p&gt;有了索引，便使保存的信息和要搜索的信息一致，可以大大加快搜索的速度。&lt;/p&gt;&#xA;&lt;p&gt;比如说，我们要寻找既包含字符串“lucene”又包含字符串“solr”的文档，我们只需要以下几步：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;取出包含字符串“lucene”的文档链表。&lt;/li&gt;&#xA;&lt;li&gt;取出包含字符串“solr”的文档链表。&lt;/li&gt;&#xA;&lt;li&gt;通过合并链表，找出既包含“lucene”又包含“solr”的文件。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://yeecode.top/blog/46/pic/003_hu_1fb3f08698bdb73c.webp&#34; alt=&#34;图片&#34; width=&#34;544&#34; height=&#34;55&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;看到这个地方，有人可能会说，全文检索的确加快了搜索的速度，但是多了索引的过程，两者加起来不一定比顺序扫描快多少。的确，加上索引的过程，全文检索不一定比顺序扫描快，尤其是在数据量小的时候更是如此。而对一个很大量的数据创建索引也是一个很慢的过程。&lt;/p&gt;&#xA;&lt;p&gt;然而两者还是有区别的，顺序扫描是每次都要扫描，而创建索引的过程仅仅需要一次，以后便是一劳永逸的了，每次搜索，创建索引的过程不必经过，仅仅搜索创建好的索引就可以了。&lt;/p&gt;&#xA;&lt;p&gt;这也是全文搜索相对于顺序扫描的优势之一：一次索引，多次使用。&lt;/p&gt;&#xA;&lt;h2 id=&#34;3-如何创建索引&#34;&gt;3. 如何创建索引&lt;/h2&gt;&#xA;&lt;p&gt;全文检索的索引创建过程一般有以下几步：&lt;/p&gt;&#xA;&lt;h2 id=&#34;31-一些要索引的原文档document&#34;&gt;3.1 一些要索引的原文档(Document)。&lt;/h2&gt;&#xA;&lt;p&gt;为了方便说明索引创建过程，这里特意用两个文件为例：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;文件一：Students should be allowed to go out with their friends, but not allowed to drink beer.&#xA;文件二：My friend Jerry went to school to see his students but found them drunk which is not allowed.&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;32-将原文档传给分次组件tokenizer&#34;&gt;3.2 将原文档传给分次组件(Tokenizer)。&lt;/h2&gt;&#xA;&lt;p&gt;分词组件(Tokenizer)会做以下几件事情(此过程称为Tokenize)：&lt;/p&gt;</description>
			</item>
			<item>
				<title>Zookeeper概述</title>
				<link>https://yeecode.top/blog/11/</link>
				<pubDate>Sat, 19 May 2018 00:00:00 +0000</pubDate>
				<guid>https://yeecode.top/blog/11/</guid>
				<description>&lt;h2 id=&#34;zookeeper简介&#34;&gt;Zookeeper简介&lt;/h2&gt;&#xA;&lt;p&gt;Zookeeper是一个高性能的分布式一致系统，在分布式系统中有着广泛的应用。基于它，可以实现分布式同步、配置管理、命名空间管理等众多功能，是分布式系统中常见的基础系统。&lt;/p&gt;&#xA;&lt;p&gt;Zookeeper主要用来解决分布式集群中应用系统的一致性问题，它有着树状结构的节点，每个节点均可存储少量的数据。同时，用户可以修改和订阅节点中的内容。分布式系统中的节点通过监控这些数据状态的变化，从而可以达到基于数据的集群管理。 &lt;/p&gt;&#xA;&lt;p&gt;从设计模式角度来看，Zookeeper是基于观察者模式实现的。可以把它作为一个信息的中心。使用该服务的生产者和消费者都以Zookeeper中的数据为基准。即：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;生产者可以改变Zookeeper的节点，或者节点上的数据&lt;/li&gt;&#xA;&lt;li&gt;消费者通过订阅Zookeeper节点，从而能够在节点变动时收到通知&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;基于这样的机制，将Zookeeper作为信息中心，便可以实现分布式系统中节点状态的最终一致性。&lt;/p&gt;&#xA;&lt;h2 id=&#34;特点&#34;&gt;特点&lt;/h2&gt;&#xA;&lt;p&gt;Zookeeper具有以下特点：&#xA; &lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;最终一致性：客户端不论连接到哪个Zookeeper的哪一个节点，都会收到同一份状态。这是zookeeper最重要的性能。 &lt;/li&gt;&#xA;&lt;li&gt;可靠性：Zookeeper集群具有简单、健壮、良好的性能，如果消息m被到一台server接受，那么它将被所有的server接受。 &lt;/li&gt;&#xA;&lt;li&gt;实时性：Zookeeper保证client将在一个时间间隔范围内获得server的更新信息，或者server失效的信息。但由于网络延时等原因，Zookeeper不能保证两个client能同时得到刚更新的数据，如果需要最新数据，应该在读数据之前调用sync()接口。 &lt;/li&gt;&#xA;&lt;li&gt;等待无关（wait-free）：慢的或者失效的client不得干预快速的client的请求，使得每个client都能有效的等待。 &lt;/li&gt;&#xA;&lt;li&gt;原子性：更新只能成功或者失败，没有中间状态。 &lt;/li&gt;&#xA;&lt;li&gt;顺序性：包括全局有序和偏序两种：全局有序是指如果在一台server上消息a在消息b前发布，则在所有Server上消息a都将在消息b前被发布；偏序是指如果一个消息b在消息a后被同一个发送者发布，a必将排在b前面。 &lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;zookeeper应用场景&#34;&gt;zookeeper应用场景&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;数据发布与订阅：应用配置集中到节点上，应用启动时主动获取，并在节点上注册一个watcher，每次配置更新都会通知到应用。 &lt;/li&gt;&#xA;&lt;li&gt;名空间服务：分布式命名服务，创建一个节点后，节点的路径就是全局唯一的，可以作为全局名称使用。 &lt;/li&gt;&#xA;&lt;li&gt;分布式通知/协调：不同的系统都监听同一个节点，一旦有了更新，另一个系统能够收到通知。 &lt;/li&gt;&#xA;&lt;li&gt;分布式锁：Zookeeper能保证数据的强一致性，用户任何时候都可以相信集群中每个节点的数据都是相同的。一个用户创建一个节点作为锁，另一个用户检测该节点，如果存在，代表别的用户已经锁住，如果不存在，则可以创建一个节点，代表拥有一个锁。 &lt;/li&gt;&#xA;&lt;li&gt;集群管理：每个加入集群的机器都创建一个节点，写入自己的状态。监控父节点的用户会受到通知，进行相应的处理。离开时删除节点，监控父节点的用户同样会收到通知。如图： &lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://yeecode.top/blog/11/pic/012_hu_f5ddeb2030da23e2.webp&#34; alt=&#34;图片&#34; width=&#34;529&#34; height=&#34;349&#34; loading=&#34;eager&#34; decoding=&#34;async&#34;&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;配置管理：在分布式应用环境中很常见，例如同一个应用系统需要多台节点运行，但是它们运行的应用系统的某些配置项是相同的，如果要修改这些相同的配置项，那么就必须同时修改每台运行这个应用系统的 PC Server，这样非常麻烦而且容易出错。像这样的配置信息完全可以交给 Zookeeper 来管理，将配置信息保存在 Zookeeper 的某个目录节点中，然后将所有需要修改的应用机器监控配置信息的状态，一旦配置信息发生变化，每台应用机器就会收到 Zookeeper 的通知，然后从 Zookeeper 获取新的配置信息应用到系统中。如图： &lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://yeecode.top/blog/11/pic/013_hu_92bca02291b99ba0.webp&#34; alt=&#34;图片&#34; width=&#34;529&#34; height=&#34;319&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
