当前位置:K88软件开发文章中心编程语言SQLscala → 文章内容

Searchbird

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-19 4:45:26

_uptime: 1671792labels:metrics: Searchbird/handletime_us: (average=9598, count=4, maximum=19138, minimum=637, p25=637, p50=4265, p75=14175, p90=19138, p95=19138, p99=19138, p999=19138, p9999=19138, sum=38393) Searchbird/request_latency_ms: (average=4, count=3, maximum=9, minimum=0, p25=0, p50=5, p75=9, p90=9, p95=9, p99=9, p999=9, p9999=9, sum=14)除了我们自己的服务统计信息以外,还有一些通用的 JVM 统计。现在,让我们来看看配置、服务器和客户端的实现代码。…/config/SearchbirdServiceConfig.scala配置是一个 Scala 的特质,有一个方法 apply: RuntimeEnvironment => T 来创建一些 T 。在这个意义上,配置是“工厂” 。在运行时,配置文件(通过使用Scala编译器库)被取值为一个脚本,并产生一个配置对象。 RuntimeEnvironment 是一个提供各种运行参数(命令行标志, JVM 版本,编译时间戳等)查询的一个对象。SearchbirdServiceConfig 类就是这样一个配置类。它使用其默认值一起指定配置参数。 (Finagle 支持一个通用的跟踪系统,我们在本教程将不会介绍: Zipkin 一个集合/聚合轨迹的 分布式跟踪系统。)class SearchbirdServiceConfig extends ServerConfig[SearchbirdService.ThriftServer] { var thriftPort: Int = 9999 var tracerFactory: Tracer.Factory = NullTracer.factory def apply(runtime: RuntimeEnvironment) = new SearchbirdServiceImpl(this)}在我们的例子中,我们要创建一个 SearchbirdService.ThriftServer。这是由 thrift 代码生成器生成的服务器类型[2]。…/Main.scala在 SBT 控制台中键入“run”调用 main ,这将配置和初始化服务器。它读取配置(在 development.scala 中指定,并会作为参数传给“run”),创建 SearchbirdService.ThriftServer ,并启动它。 RuntimeEnvironment.loadRuntimeConfig 执行配置赋值,并把自身作为一个参数来调用 apply [3]。object Main { private val log = Logger.get(getClass) def main(args: Array[String]) { val runtime = RuntimeEnvironment(this, args) val server = runtime.loadRuntimeConfig[SearchbirdService.ThriftServer] try { log.info("Starting SearchbirdService") server.start() } catch { case e: Exception => log.error(e, "Failed starting SearchbirdService, exiting") ServiceTracker.shutdown() System.exit(1) } }}…/SearchbirdServiceImpl.scala这是实质的服务:我们用自己的实现扩展 SearchbirdService.ThriftServer 。回忆一下 thrift 为我们生成的 SearchbirdService.ThriftServer 。它为每一个 thrift 方法生成一个 Scala 方法。到目前为止,在我们的例子中生成的接口是:trait SearchbirdService { def put(key: String, value: String): Future[Void] def get(key: String): Future[String]}返回值是 Future[Value] 而不是直接返回值,可以推迟它们的计算(finagle 的文档有 Future 更多的细节)。对本教程的目的来说,你唯一需要知道的有关 Future 的知识点是,可以通过 get() 获取其值。scala-bootstrapper 默认实现的 key-value 存储很简单:它提供了一个通过 get 和 put 访问的 数据库 数据结构。class SearchbirdServiceImpl(config: SearchbirdServiceConfig) extends SearchbirdService.ThriftServer { val serverName = "Searchbird" val thriftPort = config.thriftPort override val tracerFactory = config.tracerFactory val database = new mutable.HashMap[String, String]() def get(key: String) = { database.get(key) match { case None => log.debug("get %s: miss", key) Future.exception(SearchbirdException("No such key")) case Some(value) => log.debug("get %s: hit", key) Future(value) } } def put(key: String, value: String) = { log.debug("put %s", key) database(key) = value Future.Unit } def shutdown() = { super.shutdown(0.seconds) }}其结果是构建在 Scala HashMap 上的一个简单 thrift 接口。一个简单的搜索引擎现在,我们将扩展现有的例子,来创建一个简单的搜索引擎。然后,我们将进一步扩展它成为由多个分片组成的 分布式 搜索引擎,使我们能够适应比单台机器内存更大的语料库。为了简单起见,我们将最小化扩展目前的 thrift 服务,以支持搜索操作。使用模型是用 put 把文件加入搜索引擎,其中每个文件包含了一系列的记号(词),那么我们就可以输入一串记号,然后搜索会返回包含这个串中所有记号的所有文件。该体系结构是与前面的例子相同,但增加了一个新的 @search@ 调用。要实现这样一个搜索引擎需要修改以下两个文件:src/main/thrift/searchbird.thriftservice SearchbirdService { string get(1: string key) throws(1: SearchbirdException ex) void put(1: string key, 2: string value) list<string> search(1: string query)}我们增加了一个 search 方法来搜索当前哈希表,返回其值与查询匹配的键列表。实现也很简单直观:…/SearchbirdServiceImpl.scala大部分修改都在这个文件中。现在的 数据库 HashMap 保存一个正向索引来持有到文档的键映射。我们重命名它为 forward 并增加一个 倒排(reverse) 索引(映射记号到所有包含该记号的文件)。所以在 SearchbirdServiceImpl.scala 中,更换 database 定义:val forward = new mutable.HashMap[String, String] with mutable.SynchronizedMap[String, String]val reverse = new mutable.HashMap[String, Set[String]] with mutable.SynchronizedMap[String, Set[String]]在 get 调用中,使用 forward 替换 数据库 即可,在其他方面 get 保持不变(仅执行正向查找)。不过 put 还需要改变:我们还需要为文件中的每个令牌填充反向索引,把文件的键附加到令牌关联的列表中。用下面的代码替换 put 调用。给定一个特定的搜索令牌,我们现在可以使用反向映射来查找文件。def put(key: String, va

上一页  [1] [2] [3] [4] [5]  下一页


Searchbird