优化了破网站的搜索功能
大家好,我是鱼皮,今天搞一场技术实战,需求分析 = 技术选型 = 设计实现,从 0 到 1,带大家优化网站搜索的灵活性。
本文大纲:
鱼皮 - 网站搜索优化
我开发的 编程导航网站 已经上线 6 个月了,但是从上线之初,网站一直存在一个很严重的问题,就是搜索功能并不好用。
此前,为了追求快速上线,搜索功能就简单地使用了数据库模糊查询(包含)来实现,开发是方便了,但这种方式很不灵活。
举个例子,网站上有个资源叫 “Java 设计模式”,而用户搜索 “Java设计模式” 就啥都搜不出来,原因是资源名中包含了空格,而用户搜索时输入的关键词并不包含空格。
空格只是一种特例,类似的情况还有很多,比如网站上有个资源叫 “Java 并发编程实战”,但用户搜索 “Java 实战” 时,明明前者包含 “Java” 和 “实战” 这两个词,但却是什么都搜不出来的。
要知道,搜索功能对于一个信息聚合类站点是至关重要的,直接影响用户的体验。在你的网站上搜不到资源,谁还会用?
所以我也收到了一些小伙伴的礼貌建议,比如这位秃头 Tom:
之前没有优化搜索,主要是两个原因:穷 + 怕麻烦。但随着网站用户量的增大,是时候填坑了!
想要提高网站搜索灵活性,可以使用 全文搜索 技术,在前端和后端都可以实现。
有时,我们要检索的数据是有限的,且所有数据都是 存储在客户端 的。
比如个人博客网站,我们通常会把每篇文章作为一个文件存放在某目录下,而不是存在后台数据库中,这种情况下,不需要再从服务器上去请求动态数据,那么可以直接在前端搜索数据。
有一些现成的搜索库,比如 Lunr.js (GitHub 7k+ star),先添加要检索的内容:
然后搜索就可以了:
纯前端全文搜索的好处是无需后端、简单方便,可以节省服务器的压力;无需连网,也没有额外的网络开销,检索更快速。
区别于前端,后端全文搜索在服务器上完成,从远程数据库中搜索符合要求的数据,再直接返回给前端。
目前主流的后端全文搜索技术是 Elasticsearch,一个分布式、RESTful 风格的搜索和数据分析引擎。
它的功能强大且灵活,但是需要自己搭建、定义数据、管理词典、上传和维护数据等,可操作性很强,需要一些水平,新手和大佬设计出的 ES 搜索系统那是天差地别。
所以,对于不熟悉 Elasticsearch 的同学,也可以直接使用现成的全文检索服务。比如 Algolia,直接通过它提供的 API 上传需要检索的数据,再用它提供的 API 检索就行了。它提供了一定的免费空间,对于小型网站和学习使用完全足够了。
Algolia 检索服务
那么我的编程导航网站选择哪种实现方式呢?
首先,该网站的资源数是不固定的、无规律动态更新的,因此不适合前端全文检索。
其次,考虑到日后网站的数据量会比较大,而且可能要根据用户的搜索动态地去优化检索系统(比如自定义编程词典),因此考虑使用 Elasticsearch 技术 自行搭建搜索引擎,而不用现成的全文检索服务,这样今后自己想怎么定制系统都可以。此外,不用向其他平台发送网站数据,能保证数据的安全。
确定使用 Elasticsearch 后,要先搭建环境。
可以自己购买服务器,再按照官方文档一步步手动安装。对于有一定规模的个人网站来说,虽然搭建过程不难,但后期的维护成本却是巨大的,比如性能分析、监控、告警、安全等等,都需要自己来配置。尤其是后期网站数据量更大了,还要考虑搭建集群、水平扩容等等。
因此,我选择直接使用云服务商提供的 Elasticsearch 服务,这里选择腾讯云,自动为你搭建了现成的 ES 集群服务,还提供了可视化架构管理、集群监控、日志、高级插件、智能巡检等功能。
云 ES 集群架构图
虽然 ES 服务的价格贵,但节省下大量时间成本,对我来说是值得的。
我们的目标是优化网站资源的搜索功能,但接下来要做的不是直接编写具体的业务逻辑,而是先开发一个 公共的 ES 服务 。
其实对 ES 的操作比较简单,可以先简单地把它理解为一个数据库,那么公共的 ES 服务应具有基本的增删改查功能,供其他函数调用。
由于编程导航的后端使用的是腾讯云开发技术,用 Node.js 来编写服务,所以选用官方推荐的 @elastic/elasticsearch 库来操作 ES。
代码很简单,先是建立和 ES 的连接,此处为了保证数据安全,使用内网地址:
然后是编写增删改查。这里做一步 抽象 ,通过 switch 等分支语句,根据请求参数来区分操作、要操作的数据等,这样就不用把每个操作都独立写成一个接口了。
具体的增删改查代码就不赘述了,对着 ES Node 的官方文档看一遍就行了,后面会把代码开源到编程导航仓库中()。
编写好代码后,可以用云开发自带的 tcb 命令行工具在本地执行该函数。
记得先把 ES 的连接地址改成公网,然后输入一行命令就行了。比如我们要向 ES 插入一条数据,传入要执行的函数名、请求参数、代码路径:
执行成功后,就能在 ES 中看到新插入的数据了(通过 Kibana 面板或 curl 查看):
本地测试好公共服务代码后,把 ES 连接地址改成内网 IP,然后发布到云端。
接下来试着编写一个其他的函数来访问公共 ES 服务,比如插入资源到 ES,通过 callFunction 请求:
但是,数据并没有被成功插入,而是返回了接口超时,Why?
通过日志得知是 ES 连接不上,会不会是因为发布上线的 ES 公共服务所在的机器和 ES 不在同一个内网呢?
所以需要在云开发控制台更改 ES 公共服务的私有网络配置,选择和购买 ES 时同样的子网就行了:
配置 ES 云函数私有网络
修改之后,再次远程请求 ES 公共服务,数据就插入成功了~
开发好 ES 公共服务后,就可以编写具体的业务逻辑了。
首先要在 ES 中建立一个索引(类似数据库的表),来约定数据的类型、分词等信息,而不是允许随意插入数据。
比如为了更灵活搜索,资源名应该指定为 "text" 类型,以开启分词,并指定 ik 中文分词器:
***还要为索引指定一个别名,便于后续修改字段时重建索引:
编写好建立索引的 json 配置后,通过 curl 或 Kibana 去调用 ES 新建索引接口就行了。
之前,编程导航网站的资源数据都是存在数据库中的,用户从数据库中查询。而现在要改为从 ES 中查询,ES 空空如也可不行,得想办法把数据库中的资源数据同步到 ES 中。
这里有几种同步策略。
以前,用户推荐的资源只会插入到数据库,双写是指在资源插入数据库的时候,同时插入到 ES 就好了。
听上去挺简单的,但这种方式存在一些问题:
那有没有对现有代码 侵入更小 的方法呢?
如果对数据实时性的要求不高,可以选择定时同步,每隔一段时间将最新插入或修改的数据从数据库复制到 ES 上。
实现方式有很多种,比如用 Logstash 数据传输管道,或者自己编写定时任务程序,这样就完全不用改现有的代码。
如果对数据实时性要求很高,刚刚插入数据库的数据就要能立刻就能被搜索到,那么就要实时同步。除了双写外,还可以监听数据库的 binlog,在数据库发生任何变更时,我们都能感知到。
阿里有个开源项目叫 C*** ,能够实时监听 MySQL 数据库,并推送通知给下游,感兴趣的朋友可以看看。
C*** 项目
由于编程资源的搜索对实时性要求不高,所以定时同步就 ok。
云开发默认提供了定时函数功能,我就直接写一个云函数,每 1 分钟执行一次,每次读取数据库中近 5 分钟内发生了变更的数据,以防止上次执行失败的情况。此外,还要配置超时时间,防止函数执行时间过长导致的执行失败。
在云开发 - 云函数控制台就能可视化配置了,需要为定时任务指定一个 crontab 表达式:
配置云函数定时和超时
开启定时同步后,不要忘了再编写并执行一个 首次 同步函数,用于将 历史 的全量数据同步到 ES。
现在 ES 上已经有数据了,只剩最后一步,就是怎么把数据搜出来呢?
首先我们要学习 ES 的搜索 DSL(语法),包括如何取列、搜索、过滤、分页、排序等,对新手来讲,还是有点麻烦的,尤其是查询条件中布尔表达式的组合,稍微不注意就查不出数据。所以建议大家先在 Kibana 提供的调试工具中编写查询语法:
Kibana 调试
查出预期的数据后,再编写后端的搜索函数,接受的请求参数***和原接口保持一致,减少改动。
可以根据前端传来的请求动态拼接查询语法,比如要按照资源名搜索:
由此,整个网站的搜索优化完毕。
再去试一下效果,现在哪怕我输入一些多 “鱼” 的词,也能搜到了!
新 ES 搜索接口的发布并不意味着老的数据库查询接口淘汰,可以同时保留。按名称搜索资源时用新接口,更灵活;而根据审核状态、搜索某用户发布过的资源时,可以用老接口,从数据库查。从而分摊负载,职责分离,让对的技术做对的事情!
我是鱼皮,最后再送大家一些 帮助我拿到大厂 offer 的学习资料 :
指路:
欢迎阅读 我从 0 自学进入腾讯的编程学习、实习、求职、考证、写书经历,不再迷茫!
指路:
详细配置Next部分功能及插件
本篇文章只介绍配置Next主题,如若不是这个主题便可不用浏览!!!
站点配置文件 为博客目录下的 _config.yml 文件, 主题配置文件 为主题目录下的 _config.yml 文件!!!
9.先修改Schenme,我选择的是:
安装:
在站点配置文件新增如下:
在主题配置文件新增:
然后在站点配置中找到package.json, 把里面的hexo-algolia, 换成 "hexo-algolia": "^0.2.0",如图:
由此,配置完成。
NexT使用文档
邻家枫扬在知乎的回答
大都小酒馆
5.1.0使用algolia搜索问题
1022_zhang's Blog
「PostgreSQL架构」为什么RDBMS是分布式数据库的未来
大约10年前,我加入了Amazon Web Services,在那里我***次看到了在分布式系统中进行权衡的重要性。在大学里,我已经了解了一致性和可用性之间的权衡(CAP定理),但实际上,频谱要比这深得多。任何设计决策都可能涉及延迟,并发性,可伸缩性,耐用性,可维护性,功能性,操作简便性以及系统其他方面之间的权衡,而这些权衡会对应用程序的功能和用户体验产生有意义的影响,并且即使是业务本身的有效性。
也许在权衡需求最明显的分布式系统中***挑战性的问题是构建分布式数据库。当应用程序开始需要可以在许多服务器上扩展的数据库时,数据库开发人员开始做出极端的权衡。为了在许多节点上实现可伸缩性,分布式键值存储(NoSQL)抛弃了传统关系数据库管理系统(RDBMS)提供的丰富功能集,包括SQL,联接,外键和ACID保证。由于每个人都想要可伸缩性,因此RDBMS消失只是时间问题,对吗?实际上,关系数据库继续主导着数据库领域。这就是为什么:
在分布式系统(或任何系统)中进行权衡时,要考虑的最重要方面是开发成本。
数据库软件所做出的权衡将对应用程序的开发成本产生重大影响。在高级应用程序中处理需要可用性,可靠性和性能的数据是一个固有地需要解决的问题。成功解决每个小问题所需的工时数量可能很大。幸运的是,数据库可以解决许多这些子问题,但是数据库开发人员也面临成本问题。实际上,要使数据库足以满足大多数应用程序的功能,保证和性能,就需要数十年的时间。那就是建立关系数据库如PostgreSQL和MySQL的地方。
在Citus Data,我们从不同角度解决了数据库可伸缩性的需求。我和我的团队在过去的几年中花费了很多时间将已建立的RDBMS转换为分布式数据库,而又不会失去其强大功能或从基础项目中分叉。通过这样做,我们发现RDBMS是构建分布式数据库的理想基础。
使RDBMS对开发应用程序(尤其是开源RDBMS,尤其是云RDBMS)如此吸引人的原因在于,您可以有效地利用数十年来对RDBMS进行的工程投资,并利用这些RDBMS功能。您的应用,降低了开发成本。
RDBMS为您提供:
这些功能几乎对任何非平凡的应用都很重要,但是要花很长时间才能开发。另一方面,某些应用程序的工作量对于单台计算机来说太过苛刻,因此需要水平可伸缩性。
许多新的分布式数据库正在开发中,并且正在分布式键值存储(“ NewSQL”)之上实现RDBMS功能,例如SQL。尽管这些较新的数据库可以使用多台计算机的资源,但是在SQL支持,查询性能,并发性,索引,外键,事务,存储过程等方面,它们仍远未建立在关系数据库系统上。您遇到许多要在应用程序中解决的复杂问题。
许多大型互联网公司采用的替代方法是RDBMS的手动,应用程序层分片(通常是PostgreSQL或MySQL)。手动分片意味着有许多RDBMS节点,并且应用程序会根据某种条件(例如,用户ID)决定连接到哪个节点。应用程序本身负责如何处理数据放置,架构更改,查询多个节点,复制表等,因此,如果执行手动分片,最终将在应用程序中实现自己的分布式数据库,这可能甚至更多。昂贵。
幸运的是,有一种方法可以解决开发成本难题。
PostgreSQL已有数十年的发展 历史 ,其令人难以置信的重点是代码质量,模块化和可扩展性。这种可扩展性提供了一个独特的机会:无需分叉就可以将PostgreSQL转换为分布式数据库。这就是我们构建Citus的方式。
大约5年前,当我加入一家名为Citus Data的初创公司时,我为在竞争激烈的市场中建立高级分布式数据库而无任何现有基础架构,品牌知名度,进入市场,资本或大量工程师的挑战感到沮丧 。 仅开发成本就似乎是无法克服的。 但是,就像应用程序开发人员利用PostgreSQL来构建复杂的应用程序一样,我们利用PostgreSQL来构建……分布式PostgreSQL。
我们创建了Citus,这是开源的PostgreSQL扩展,而不是从头开始创建分布式数据库,它以提供水平扩展的方式透明地分发表和查询,但是应用程序开发人员需要具备所有PostgreSQL功能才能成功。
通过使用在计划查询时Postgres调用的内部挂钩,我们能够将分布式表的概念添加到Postgres。
分布式表的分片存储在具有所有现有功能的常规PostgreSQL节点中,Citus发送常规SQL命令以查询分片,然后合并结果。 我们还添加了参考表的概念,该参考表可在所有节点上复制,因此可以通过任何列与分布式表连接。 通过进一步增加对分布式事务,查询路由,分布式子查询和CTE,序列,更新等的支持,我们达到了***进的PostgreSQL功能可以使用的规模,但现在已经可以大规模使用。
Citus相对来说还很年轻,但是已经建立在PostgreSQL之上,已经成为世界上***进的分布式数据库之一。与PostgreSQL的完整功能集相比,这令人毛骨悚然,还有许多工作要做,Citus现在提供的功能及其扩展方式使其在分布式数据库环境中具有很大的独特性。许多当前的Citus用户最初使用Postgres中的许多高级功能在单节点PostgreSQL服务器上建立业务,然后仅用几周的开发工作就迁移到Citus,以将其数据库模式转换为分布式表和引用表。对于任何其他数据库,从单节点数据库到分布式数据库的这种迁移可能要花费数月甚至数年的时间。
像PostgreSQL这样的RDBMS具有几乎无限的功能和成熟的SQL引擎,可让您以多种方式查询数据。当然,这些功能只有在速度很快时才对应用程序有用。幸运的是,PostgreSQL很快,并且通过诸如实时查询编译之类的新功能不断提高,但是当您拥有大量数据或流量以至于一台机器速度太慢时,那些强大的功能就不再那么有用了……除非您可以结合许多计算机的计算能力。这就是功能成为超级大国的地方。
通过采用PostgreSQL功能并进行扩展,Citus具有许多超级功能,这些功能使用户可以将数据库扩展到任意大小,同时保持高性能及其所有功能。
尽管大多数这些功能对于开发需要扩展的复杂应用程序来说似乎都是必不可少的,但并不是所有分布式数据库都支持它们。下面我们根据公开提供的文档对一些流行的分布式数据库进行比较。
与在分布式数据库中拥有超级功能相比,更重要的是能够组合数据库超级功能来解决复杂的用例。
由于支持查询路由,参考表,索引,分布式事务和存储过程,因此即使***进的多租户OLTP应用程序(例如Copper)也可以使用Citus扩展到单个PostgreSQL节点之外,而不会在应用程序中做出任何牺牲。
如果将子查询下推与并行的分布式DML结合使用,则可以在数据库内部转换大量数据。一个常见的示例是使用INSERT…SELECT构建汇总表,该表可以并行化以适应任何类型的数据量。结合通过COPY,索引,联接和分区进行的批量加载,您将拥有一个非常适合时间序列数据和实时分析应用程序(如Algolia仪表板)的数据库。
正如Microsoft的Min Wei在谈到Microsoft如何使用Citus和PostgreSQL分析Windows数据时指出的那样:Citus使您能够使用分布式OLTP解决大规模OLAP问题。
Citus与其他分布式数据库有些不同,后者通常是从头开始开发的。 Citus没有引入PostgreSQL中尚未提供的任何功能。 Citus数据库以满足需要扩展的用例的方式扩展了现有功能。重要的是,大多数PostgreSQL功能已经针对各种用例进行了数十年的开发和测试,而当今用例的功能要求最终并没有太大不同;主要是数据的规模和大小不同。因此,在构建现代应用程序时,基于世界上***进的开源RDBMS(PostgreSQL!)构建的分布式数据库(如Citus)可以成为您的武器库中最强大的工具。
原文:
本文:
讨论:请加入知识星球或者微信圈子【首席架构师圈】
有没有人站内搜索用过Algolia,具体Index怎么配置
游戏的运行和机器的CPU,内存,独立显示核心等硬件配置有直接的关系,另外也和系统,驱动,其他软件等也有联系。当前,是否可以玩一个游戏,首先需要查看游戏运行的配置要求和机器的配置要求做一个对比,查看机器的配置是否符合。如果可以满足游戏的***运行需求,则可以支持。"
使用Laravel5.3中的Scout,默认搜索是algolia,对中文的支持好吗
Laravel5.3中的Scout,默认搜索是algolia,对分词不好,直接搜索中文的话不会自己切词,只会包含搜索的词会出现
完美app反馈谁都可以看到吗
独立个人开发者,肯定会看的,无论是评级还是邮件反馈,都会看的。好评论会回复的,有时候有些无理取闹的评论会不理睬或者怂上一顿 。毕竟自己的孩子谁不会好好养呢?除非不想养了。
对于大厂,部分大厂还是会看的,并且会主动联系你,目前主动联系我的包括:QQ产品团队,Worktile 团队,知乎团队,Algolia团队,Coursera 团队等等。
algolia的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于algolia search、algolia的信息别忘了在本站进行查找喔。