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

Searchbird

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

erverConfig[SearchbirdService.ThriftServer] { var thriftPort: Int = 9999 var shards: Seq[String] = Seq() def apply(runtime: RuntimeEnvironment) = { val index = runtime.arguments.get("shard") match { case Some(arg) => val which = arg.toInt if (which >= shards.size || which < 0) throw new Exception("invalid shard number %d".format(which)) // override with the shard port val Array(_, port) = shards(which).split(":") thriftPort = port.toInt new ResidentIndex case None => require(!shards.isEmpty) val remotes = shards map { new RemoteIndex(_) } new CompositeIndex(remotes) } new SearchbirdServiceImpl(this, index) }}现在,我们将调整配置:添加“分片”初始化到 SearchbirdServiceConfig 的初始化中(我们可以通过端口 9000 访问分片 0,9001 访问分片 1,依次类推)。config/development.scalanew SearchbirdServiceConfig { // Add your own config here shards = Seq( "localhost:9000", "localhost:9001", "localhost:9002" ) ...注释掉 admin.httpPort 的设置(我们不希望在同一台机器上运行多个服务,而不注释的话这些服务都会试图打开相同的端口): // admin.httpPort = 9900现在,如果我们不带任何参数调用我们的服务器程序,它会启动一个主节点来和所有分片通信。如果我们指定一个分片参数,它会在指定端口启动一个分片服务器。让我们试试吧!我们将启动 3 个服务:2 个分片和 1 个主节点。首先编译改动:$ ./sbt> compile...> exit然后启动三个服务:$ ./sbt 'run -f config/development.scala -D shard=0'$ ./sbt 'run -f config/development.scala -D shard=1'$ ./sbt 'run -f config/development.scala'您可以在 3 个不同的窗口中分别运行,或在同一窗口开始依次逐个运行,等待其启动后,只用 ctrl-z 悬挂这个命令,并使用 bg 将它放在后台执行。然后,我们将通过控制台与它们进行互动。首先,让我们填充一些数据在两个分片节点。从 searchbird 目录运行:$ ./console localhost 9000...> client.put("fromShardA", "a value from SHARD_A")> client.put("hello", "world")$ ./console localhost 9001...> client.put("fromShardB", "a value from SHARD_B")> client.put("hello", "world again")一旦完成就可以退出这些控制台会话。现在通过主节点查询我们的数据库(9999 端口):$ ./console localhost 9999[info] Running com.twitter.searchbird.SearchbirdConsoleClient localhost 9999'client' is bound to your thrift client.finagle-client> client.get("hello").get()res0: String = worldfinagle-client> client.get("fromShardC").get()SearchbirdException(No such key)...finagle-client> client.get("fromShardA").get()res2: String = a value from SHARD_Afinagle-client> client.search("hello").get()res3: Seq[String] = ArrayBuffer()finagle-client> client.search("world").get()res4: Seq[String] = ArrayBuffer(hello)finagle-client> client.search("value").get()res5: Seq[String] = ArrayBuffer(fromShardA, fromShardB)这个设计有多个数据抽象,允许更加模块化和可扩展的实现:ResidentIndex 数据结构对网络、服务器或客户端一无所知。CompositeIndex 对其索引构成的底层数据结构和组合方式一无所知;它只是简单地把请求分配给他们。服务器相同的 search 接口(特质)允许服务器查询其本地数据结构(ResidentIndex) ,或分发到其他服务器(CompositeIndex) 查询,而不需要知道这个区别,这是从调用隐藏的。SearchbirdServiceImpl 和 Index 现在是相互独立的模块,这使服务实现变得简单,同时实现了服务和其数据结构之间的分离。这个设计灵活到允许一个或多个远程索引运行在本地机器或远程机器上。这个实现的可能改进将包括:当前的实现将 put() 调用发送到所有节点。取而代之,我们可以使用一个哈希表,将 put()调用只发送到一个节点,而在所有节点之间分配存储。但是值得注意的是,在这个策略下我们失去了冗余。我们怎样在不需要完全复制的前提下保持一定的冗余度呢?当系统出错时我们没有做任何有趣的处理(例如我们没有处理任何异常)。[1]本地 ./sbt 脚本只是保证该 SBT 版本和我们知道的所有库是一致的。[2] 在 target/gen-scala/com/twitter/searchbird/SearchbirdService.scala 。[3] 更多信息见 Ostrich’s README 。

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


Searchbird