说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

Algolia的分布式搜索网络架构

HTML文档下载 WORD文档下载 PDF文档下载
本文是Algolia对其REST API建立和扩展经验的总结,其中包括如何在全世界不同位置保障数据的高可用和一致,以及如何通过Anycast DNS将查询路由到离用户地理位置最近的服务器。

Algolia是一家做离线移动搜索引擎的公司,两年时间构建了世界范围的分布式网络。今天为世界12个区域每月20亿用户查询,平均服务器时间为6.7ms,90%的查询应答<15ms,不可用率低于十的负六次方,及每月宕机时间<3s……

本文是Algolia对其REST API建立和扩展经验的总结,其中包括如何在全世界不同位置保障数据的高可用和一致,以及如何通过Anycast DNS将查询路由到离用户地理位置最近的服务器。它的架构有哪些独到之处,本文进行了详细解析。

以下为译文

Algolia创建于2012年,其业务是为移动设备提供一个离线搜索引擎SDK。Julien 表示,在公司创建时,他们从未想过能建立一个为全世界使用的分布式搜索网络。

当下,Algolia每月需要支撑来自全世界12个地区用户产生的20亿次以上搜索。如此规模下,Algolia仍然可以将服务器响应时间控制在6.7毫秒,并在15毫秒内为用户返回结果。Algolia服务的不可用比率低于十的负六次方,也就是服务每个月宕机时间被控制在3秒以内。

基于移动的性质,其离线移动SDK所面临的技术限制被放大。同时,因为无法使用传统服务器端的一些设计理念,Algolia必须制定独特的策略来应对这些挑战。

数据体积的误解

在架构设计之前,我们必须准确定位我们业务的使用场景。在考虑业务扩展需求时,这么做尤其重要。我们必须充分了解用户需要索引的数据体积,GB、TB或者是PB。取决于需要支撑的用例,架构将变得完全不同。

在提到搜索时,人们首先想到的就是一些非常大的用例,比如Google的网页索引,又或是Facebook基于数万亿post的索引。冷静下来,并思考每天所见到的各种搜索框,你就会发现,它们中大部分都不是基于一个规模很大的大数据集。举个例子,Netflix的搜索建立在大约1万个标题之上,而Amazon美国数据库则包含了2亿个左右的商品。到这里,你就会发现,针对上述用例,只需要使用1台服务器就可以支撑所有数据!当然,这里并不是说将数据储存在一台主机上是一个很好的思路,但是必须考虑到的是,跨主机同步将造成大量的复杂性和性能损耗。

高可用性打造途

在SaaS API建立时,高可用是个需要重点关注的领域,因为移除单点故障(SPOF)确实非常困难。经过数个星期的头脑风暴,我们终于设计出了属于我们自己的最佳架构,一个面向用户的搜索架构。

主从 vs. 主主

不妨临时缩小一下使用场景,将用例看成“索引只储存在1台主机上”,那么可用性打造将简化为“将服务器放到不同的数据中心”。通过这个设置,我们可以想到的第一个解决方案就是使用主从的架构,主服务器负责接收所有索引操作,随后在1个或多个从服务器上备份。通过这个途径,我们可以很便捷地在所有服务器上做负载均衡。

然后,问题出现了,这种架构设计只保障了搜索查询的高可用。对于一个服务公司来说,将所有索引操作传输到主服务器这种架构隐藏着非常大的风险。因为一旦主服务器宕机,所有客户端都会出现索引错误。

因此,我们必须实现一个主主架构,而主主架构设计的关键元素就是如何在一组服务器进行结果同步。这样一来,我们需要做的就是在任何情况下系统的一致性,即使在主机之间存在网络分割。

引入分布式一致性

对于一个搜索引擎来说,想实现分布式一致性就必须将写入操作串连成一个独特的有序操作流。如果在同一时间出现数个操作进入的情况,系统必须为每个操作分配一个sequence ID(序列化的ID)。通过这些ID,系统可以保障所有的备份上都在执行正确的操作序列。

而想要得到一个sequence ID(每个作业流入都会增加1),我们必须在主机间下一个sequence ID 上拥有一个共享的全局状态。在这里,开源软件ZooKeeper是个常用的选择,我们开始时也通过下述几个步骤使用了ZooKeeper:

Step 1:当某台主机接收到一个作业时,它会使用一个临时名称将作业复制到所有的副本。
Step 2:主机获取分布式锁。
Step 3:在所有主机上从ZooKeeper中读取最新的sequence ID,并发送一个命令来拷贝临时文件作为“sequence ID + 1”操作。这个步骤等同于一个二阶段提交。
Step 4:如果从大多数(法定)主机中收到确定信息,即把 Zookeeper中将sequence ID + 1。
Step 5:释放分布式锁。
Step 6:最终,发送作业的客户端将收到结果。大部分情况下,都可以得到理想的结果。

不幸的是,这种序列化并不能运用到生产环境中,如果获取分布式锁的主机崩溃,或者在执行步骤3、4时重启,我们很可能面临这样一个情况:作业在部分主机上提交成功。这样一来,我们需要一个更复杂的序列解决方案。

通过TCP连接将 ZooKeeper打包成一个外部服务的方式无形中提高了ZooKeeper的使用门槛,同时还需要使用一个非常大的timeout(默认设置是4秒)。

因此,任何故障发生时,不管是因为硬件还是软件,在整个timeout设置的时间内,系统将被冻结。看起来似乎可以接受,但是在Algolia的场景下,我们需要一个频度很高的生产环境故障测试(类似Netflix的Monkey测试方法)。

Raft一致性算法

幸运的是,当我们遭遇这些问题时,Raft一致性算法发布了。很明显,这个算法非常适合我们的用例。RAFT的状态机就是我们的索引,而日志则是待执行的索引作业列表。在PAXOS协议和它的变体上我已经有了一定的了解,但是并没有深刻到有足够的信心去亲自实现,而RAFT则更加的清晰明了。虽然当时RAFT还没有稳定的开源实现,但是很清楚的是它可以完美地匹配我们需求,而我也有足够的信心基于它来设计我们的架构

对于一致性算法实现来说,其最难的部分就是保证系统中不存在任何bug。为了保障这一点,我选择了monkey方法进行测试,在重新启动之前使用sleep来随机kill一个进程。为了更进一步地测试,我甚至通过防火墙来模拟网络中断和降级(degradation)。这种类型的测试帮助我们发现了很多bug,而在连续多天无故障运行后,我非常确认这个实现没有问题。

应用程序还是文件系统等级复制?

取代在文件系统上复制最终结果,我们决定将写入操作分配到所有主机上本地执行。做这个选择主要基于以下两个原因:

  • 这样做更快。索引在所有主机上并行进行,显然快于复制体积可能会很大的结果(二进制文件)。
  • 与多个区域策略兼容。如果在索引后复制,我们需要一个进程重写全部的索引。这意味我们可能需要传输非常大的数据,而在全球不同地理位置做大规模数据传输显然是没有效率的,比如从伦敦到新加坡。

每台主机都会使用一个正确的顺序接收所有写入操作作业,并立刻独立处理。也就是说,所有的机器最终都会在一个相同的状态,但是同一时刻的状态可能不同。

一致性上的妥协

在分布式计算环境下,CAP定理表示分布式系统不可能同时满足以下3个特性:

  • Consistency(一致性):同一时刻所有节点上的数据都相同。
  • Availability(可用性):保证每个请求都会收到其成功与否的响应。
  • Partition tolerance(分区容错性):任何消息丢失,或者系统的任何部分发生故障,系统都可以持续良好运行。

在这里,我们在一致性上做出了让步。我们不保证同一时刻所有节点上的数据相同,但是它们最后必然得到更新。换句话说,我们允许小型场景中节点不同步的情况。事实上这并不会造成问题,因为当一个用户执行一个写入操作时,我们会在所有主机上执行这个作业。在更新时间上,最先更新的主机与最后更新的主机之间不会超过1秒,因此通常情况下终端用户根本感受不到。唯一不一致的可能就是最新收到的更新是否已经被执行,然而这与我们的用例并不矛盾。

总体架构

集群的定义

在主机间保持分布式一致性是高可用基础设施打造的必备条件,然而不幸的是,这正是系统性能的一大瓶颈所在。一致性保障需要主机间的多次交互,因此每秒能达成的一致性保障数量与主机间存在的延时戚戚相关。也就是说,主机必须尽可能近才能获得每秒更高数量的一致性保障。这样一来,为了支撑多个不同的地理位置,同时还不会降低写入操作的性能,我们需要搭建多个集群,每个集群都拥有3台主机来充当备份机。

对于一致性来说,每个地区最少拥有1个集群,但是这显然并不如人意:

  • 我们不可以将所有用户请求塞进同一台主机里。
  • 用户数量越多,每个用户每秒可以执行的写入操作越少,这是因为每秒能达成的一致操作数量是固定的。

为了解决这一问题,我们决定在地区等级上使用相同的概念:每个地区都拥有多个由3台主机组成的集群。每个集群可以处理1个以上的客户,数量由客户的数据体积决定。这个观念类似于在物理机上做虚拟化,我们可以将多个客户放到同一个集群中,除下某个用户出现动态增长或者改变其使用率。为了实现这个目标,我们需要提升或自动化下面几个操作:

  • 当某个集群上数据或者写入操作数量过多时,将其中的一个客户迁移到另一个集群。
  • 如果查询的体积过大,为集群添加新主机。
  • 如果客户的数据量过大,改变分区数量,或者将其跨多集群切分。

在使用了上述策略后,一个客户不可能永远分配给一个集群。分配取决于个人使用情况和集群使用情况。这样一来,我们需要一个方案将客户分配给指定的集群。

将一个客户分配给一个集群

通常情况下,为客户分配集群的方法是为每个客户都配置一个唯一的DNS入口,类似Amazon Cloudfront的工作方式,每个客户通过customerID.cloudfront.net表格获得一个唯一的DNS条目(DNS entry),随后根据客户被分配到不同集合的主机上。

我们也决定使用这个方法。每个客户被分配一个唯一的应用程序ID,对应APPID.algolia.io表格中的DNS记录。DNS记录会指定特定的集群,因为该集群中所有主机都属于该DNS记录的一部分,所以这里存在一个通过DNS完成的负载均衡。我们同样使用健康检查机制来检测主机故障,一旦发现即会将故障机从DNS解析中移除。

单靠健康检查机制并不能提供一个很好的SLA,即使在DNS记录上配置一个很低的TTL(TTL是客户被允许缓存的DNS answer时间)。这里存在的问题是在主机发生故障时,用户仍然可能缓存这台主机。在缓存期满前,用户仍然会不停地给这台主机发送查询。在很多情况下,系统可能不遵守TTL设置。在实际操作中,我们看到1分钟的TTL可能会被某些DNS服务器修改成30分钟的TTL。

为了进一步提高可用性,以及避免主机故障对用户的影响,我们为每个客户生成了另一组DNS记录,APPID-1.algolia.io、APPID-2.algolia.io以及APPID-3.algolia.io。这么做是为了当TCP连接超时后,API客户端可以重新尝试其他的DNS记录。我们的实现是对DNS记录进行shuffle,然后按照顺序重试。

对比使用一个专业的负载均衡器,严格地控制重试配合API客户端中的超时逻辑,系统获得了一个更健壮及开销更小的客户分配机制。

随后,我们发现流行的.IO TLD在性能方面表现并不如人意。对比.IO,在anycast network情景下,.NET可以拥有更多的DNS服务器。为了解决.IO因为大量超时导致的域名解析变慢,我们切换到了algolia.net域名,同时向后兼容algolia.io域名。

集群的可扩展性如何?

在不会潜在影响现有客户的情况下,因为多了集群间的隔离,多集群允许服务支撑更多的客户。但单集群所面临的扩展性问题仍需考虑。

基于写的一致性保障,每秒写入操作数量成为集群扩展性的首要限制因素。为了移除这个限制,在保证一致性确认正常进行的基础上,我们在API中添加了大量的方法将一组写入操作压缩成一个操作。但是这里仍然存在问题,一些客户仍然不使用批量的方式执行写入操作,从而影响到集群中其他用户的索引速度。

为了减少这种情况下的性能下降,我们对架构做如下两个改变:

  • 添加一个批量策略,在一致性确认产生争用时,会以一致性确认为前提,自动将每个客户的写入操作整合成一个。在实际操作中,这么做意味着重置作业的顺序,但是并不会影响到操作的语义。举个例子,如果有1000个作业在争夺一致性确认资源,其中990个都来自同一个客户,我们会将这990个写入操作合并成一个,即使在顺序上这990个作业中间可能会穿插一些其他用户的作业。
  • 基于应用程序ID,增加一个一致性调度器(consensus scheduler)来控制每秒需要做一致性确认的写入操作数量,这样可以避免某个客户占用所有带宽的情况。

在实现这些提升之前,我们通过返回一个429 HTTP 状态码来控制速率限制。但是很快就被证明这个处理方式会大幅度影响用户体验,客户不得不等待它的响应,随后再进行重试。当下,我们最大的客户在一个3主机的集群上每天执行10亿次的写入操作,平均下来每秒1.15万次,最高峰值每秒可达15万。

第二个问题则是选择最合适的硬件设置,从而避免类似CPU/IO等潜在的瓶颈,以避免对集群扩展性产生影响。自开始起,我们就选择了使用自己的实体服务器,从而可以完全控制服务的性能,并避免资源的浪费。而长久以来,我们在选择合适硬件的过程中不停碰壁。

在2012年底,我们从一个较低的配置开始:Intel Xeon E3 1245v2、2x Intel SSD 320 series 120GB in raid 0以及32GB of RAM。这个配置的价格非常合理,也比云平台更加强大,同时允许我们在Europe和US-East提供服务。

这个配置允许我们针对I/O调度来调整内核及虚拟化内存,这对硬件资源的最佳利用至关重要。即使如此,我们很快发现服务受到内存和I/O限制。在那个时候,我们使用10GB的内存做索引,因此只剩下20GB的内存来缓存文件用于搜索查询。鉴于提供毫秒级响应时间的服务指标,客户索引必须放在内存中,而20GB的容量实在太小了。

在第一个配置之后,我们尝试使用不同的硬件主机,比如单/双CPU、128GB及256GB内存,以及不同大小和型号的SSD。

在多次尝试之后,我们终于找到了最佳设置:Intel Xeon E5 1650v2、128GB内存以及 2x400GB Intel S3700 SSD。在持久性上,SSD的型号非常重要。在发现正确的型号之前,多年使用中我们损坏了大量的SSD。

最终,我们建立的架构允许我们在任何地区进行良好的扩展,只要满足一个条件:在任何时候都需要拥有可用资源。也许你会感觉很奇怪,在2015年的当下我们还在考虑维护实体服务器,但如果聚焦服务质量和价格就会发现这一切都是值得的。对比使用AWS,我们可以将搜索引擎在3个不同的地理位置备份,完全置于内存,从而获得一个更好的性能。

复杂性

控制进程的数量

每台主机只包含3个进程。第一个是将所有查询解释代码嵌入到一个模块的nginx服务器。为了响应一个查询,我们在内存中映射了索引文件,并在nginx工作者进程内部直接执行查询,从而避免与任何进程或者主机通信。唯一罕见的例外情况就是客户数据无法在同一台主机上保存。

第二个进程是redis键值存储,我们使用它来检查速度和限制,并使用它为每个应用程序ID存储实时日志和计数器。这些计数器被用于建立我们的实时仪表盘,当用户连接到账号时就可以被查看,在做最近一次API调用可视化及debug上很有帮助。

最后一个进程就是生成器(builder)。这个进程负责处理所有的写入操作。当nginx进程收到一个写入操作时,它会将操作转发到生成器来执行一致性检查。同时,它还负责建立索引,并包含了大量用于检查服务错误的监视代码,比如崩溃、索引缓慢、索引错误等。基于问题的严重性,有些会通过Twilio的API以SMS告知,而有些则直接报告给PagerDuty。一旦在生产环境中发现某个错误,而这个错误并没有得到相应的报告,那么随后我们就会将之记录用于以后该种类型错误的处理。

易于部署

简单的堆栈可以非常便捷地部署。在代码部署之前,我们进行了大量的单元测试以及非回归测试(Non-Regression Test )。在所有测试都通过之后,我们就会逐步的部署到集群。

对于服务供应商来说,我们的测试应该做到生产环境的零影响,并对用户透明。同时,我们还期望在一致性确认过程中营造主机故障的场景,并检查所有事情是否如按预期进行。为了实现这两个目标,我们独立部署集群中的每台主机,并遵循以下步骤:

  1. 获取新的nginx和builder二进制文件
  2. 重启nginx网络服务器,并且在零用户查询丢失的情况下重新发布新的nginx。
  3. 关闭并发布新的builder。这将在主机的部署上触发一个RAFT故障,可以让我们确保故障转移是否如预期进行。

在架构衍变过程中,减少系统管理复杂性同样是一个坚持不懈的目标。我们不期望部署被架构约束。

实现全球覆盖

服务变得越来越全球化,在地球上某个区域支撑所有区域的查询显然是不切实际的。举个例子,如果把服务托管在US-East的主机肯定会对其他地区用户的可用性产生影响。在这种情况下,US-East的用户延时可能只有几毫秒,而亚洲客户的延时却可能达到数百毫秒,这还是没有计算海外光纤饱和所带来的带宽限制。

在这个问题的解决上,我们看到许多公司都为搜索引擎搭载了CDN。对于我们来说,对比得到的好处,这么做将造成更多的问题:在改善被频繁提交的那么一小部分查询的同时,却带来了无效缓存这个噩梦。对于我们来说,最实际的方法就是在不同的地理位置进行备份,并将之加载到内存中以提升查询效率。

这里我们需求的是一个在已有集群备份上的区域内复制。副本可以储存在一台主机上,因为这个副本将只负责搜索查询。所有写入操作将仍然传输到客户的原始集群上。

每个客户都可以选择数据备份托管的数据中心,因此某个区域中的备份机可以从多个集群中接收数据,并拥有集群将数据发送到多个备份。

基于操作流,这个机制同样被用于一致性。在一致性确认之后,每个集群负责转换自己的写入操作流到一个版本,从而每台备份机都可以使用空作业替换掉与这次复制无关的作业。随后,这个操作流会被发送到所有副本做批量操作,以尽可能地避免延时。单个发送作业会造成备份机之间的太多交互确认操作。

在集群上,写入操作会一直保存在主机上,直到它被所有的备份机确认。

DNS的最后一部分处理是将用户重定向到离自己最近的地理位置,为了保证这一点,我们在APPID-dsn.algolia.net 表格中加了另一条DNS记录以处理最近数据中心问题。最初我们使用的是Route53 DNS,但是不久后就碰到了限制。

基于延时的路由机制受限于AWS regions,因为我们有很多AWS未覆盖的地理位置,比如印度、香港、加拿大和俄罗斯。

基于地理位置的路由很糟糕,你需要为每个国家指出DNS解析是什么。许多托管DNS提供商都使用了这个传统途径,但是在我们用例中很难支持这点,也无法提供足够的相关性。举个例子,我们在美国就拥有了多个数据中心。

在做了大量的基准测试和讨论后,我们基于以下几个原因考虑使用NSOne:

对于我们来说,他们的Anycast网络非常适合,负载均衡性也做的更好。举个例子,他们在印度和非洲都拥有一个POP。

他们的过滤逻辑非常好。我们可以为每个用户指定与之相关的主机(包括备份机),并通过地理过滤器根据距离将他们分类。

他们支持EDNS客户端子网。同时,我们使用终端用户的IP而不是他们DNS服务器的IP。

在性能方面,我们实现了全球范围内的秒级同步,你可以在Product Hunt's search(托管在US-East、US-West、India、Australia和Europe)或者。Hacker News' search (托管在US-East、US-West、India和Europe)进行测试。

总结

我们花费了大量时间以打造一个分布式、可扩展的架构,也遭遇了各种不同的问题。我希望通过本文让你对我们处理问题的途径有一定的了解,并为读者打造服务提供一定的指导。

在这段时间里,我们看到越来越多开发者面临与我们类似的问题,他们使用多区域数据中心来支撑世界各地的用户,同时也拥有需要在全球范围内做一致性保障的业务,比如登陆或内容,而多区域数据中心已经成为拥有良好用户体验的必然条件。

关于作者:Julien Lemoine,Algolia的联合创始人兼CTO,Algolia是一个开发者友好的搜索即服务API,可以在毫秒级提供数据库搜索结果。

原文链接:The Architecture of Algolia’s Distributed Search Network (译者/薛童阳 责编/钱曙光) 


OpenCloud 2015将于2015年 4月16-18日在北京召开。大会包含“2015 OpenStack技术大会”、“2015 Spark技术峰会”、“2015 Container技术峰会”三大技术峰会及多场深度行业实战培训,主题聚焦技术创新与应用实践,荟萃国内外真正的云计算技术的大牛讲师。这里都是一线接地气的干货,扎实的产品、技术、服务和平台。OpenCloud 2015,懂行的人都在这里!

更多讲师和日程信息请关注OpenCloud 2015介绍和官网。

如何在程序中动态取得Win95/98的网络邻居中的工作组及计算机名?-Delphi资料 提高客户机/服务器应用系统性能的一些方法-Delphi资料 网络和通讯编程-Delphi资料 WebBrowser流程讲解及如何判断下载网页成功-Delphi资料 用Delphi 3.0实现运行于浏览器内的客户 用Delphi编写ASP的ActiveX 用Delphi编写CGI程序(五) 用Delphi编写CGI程序返回图象 用Delphi程序获取拨号连接的动态IP地址 用Delphi创建Internet快捷方式 用Delphi实现NetBIOS广播收发 用Delphi实现网络驱动器的映射和断开 用Delphi实现远程屏幕抓取 用DELPHI制作留言板 再谈用Delphi程序获取拨号连接的动态IP地址 在DELPHI程序中拨号上网 在DELPHI程序中获取网络资源信息 在Delphi程序中应用IE浏览器控件 在Delphi中调用NetscapeNavigator 在Delphi中使用flash控件 在Delphi中使用IP控件 在程序中动态取得Win95/98网络邻居中工作组及计算机名-Delphi资料 在程序中获取网络资源信息-Delphi资料 自制THyperLink组件-Delphi资料 报表制作技巧(三)-Delphi资料 Delphi数据库开发及统计表格设计 Delphi文本和图形的打印方法 Delphi应用程序中中国式报表的制作 Windows环境下实时列表输出的实现方法-Delphi资料 报表制作技巧(二)-Delphi资料 Delphi编制的程序运行中动态制作报表 sos~~!!! 需要查找Java文件注释代码行的正则表达式 一个关于格式转换的问题--急!急! 放牛娃!!! C++注释的正则表达式怎么写 请教weblogic+jb8运行jsp网页出错,thx了先 高人请进~~~~~~~~~~~~~~~~~~~~~ 毕业设计,十万火急,请各路高手多多帮忙。 很奇怪,帮我解释一下!Page_Load未执行! 问题可能较简单,但比较实用,关于打印一行的问题。 如何用FTP.EXE实现断点续传的问题? 怎么取得Client端的网卡地址? 如何使datetimepicker返回的值只有4位年和两位月 求ComboBox DataBinding 到 DataTable某个字段的方法。 请问SMTP中如何进行身份验证? 关键域刷新问题????? 为什么我的mouse_event 函数不能用 ? 当我设置EnableViewState=false,DataList事件模型出问题了。。。 请问如何制作特效界面? 上海日記:主動/被動 上海日記:上海嘉定 时间设置问题 求for语句详解 如何实现BEAN异步调用或进程间通讯 谁能告诉我金锋文件加密器4。3的注册机 有什么软件可以给程序加30天试用期?? 今天和公司老总提辞职的事情!!!! 为什么不显示我的说明文字了? 请问VC中有没有方法可以取得一幅图片上某个点的颜色值? hgknight(江雨.net)等大侠请看看一个treeview的问题!谢谢。 道德<--->迷信 求查找所有表的SQL 在纯dos下怎么建文本文档和批处理文件? 怎样设定DB2的ODBC数据源参数?谢谢先 如何将DBGrid的指定列冻结? xwindows设置的问题 请大家帮个忙好吗? 【求助】:如何在asp中调用activereport? MM,有个难题急需解决(关于 DateTimePicker控件的) 散分!! 关于怎样传递事件 用ADO连接数据库时,怎么查询数据库中存在的表? 关于生成计算列的问题 你遇见过这样的问题么? 为什么ListBox和NoteBook建立不了联系? asp连接 oracle数据库 vb和access数据库的编程思想 谈一谈VB中Get返回对象时的效率问题(三层开发相关) 如果判断一个文本框中只能输入汉字!,急用 函数function Read(maxsize: SYSINT; var data: PSafeArray): SYSINT;怎么调用? 大家帮个忙好吗? 请问玻璃移门的胶条怎么装比较快速请回答 bad和badly的区别例如词性,用法 声音在各种物质中的传播速度各为多少? 《藤野先生》里作者先离开东京,又离开仙台,两次选择的目的是什么(这我知道了)他的人生目标对你有何启 bad做副词时和badly的区别?网上好多都说bad和badly的区别就是,bad是形容词,badly是副词,但是bad也可以做副词啊!我是指二者用法的区别(在语法中),不是汉语意思 奇怪的红光昨天晚上11点多的时候 我躺在床上看电视 忽然看见从窗帘的缝隙处进来一术红光 打在墙上 一块方形的红色 有四平米左右 我当时第一反映是车灯打的 可是车灯哪里有红色的 持续 求行程问题,初一的那个,谢谢 如果一个物体达到光速会怎样 “筱”是会意字吗?怎么用“六书”造字法解释“筱”字啊? 北京大还是东京大 不知道光速是怎么达到的 英语翻译 波胆什么意思解释下? 如图,空间存在水平向右的匀强电场.在竖直平面上建立平面直角坐标,在坐标平面的第一象限内固定绝缘光滑的半径为R的1/4圆周轨道,轨道的两端在坐标轴上.质量为m的带正电的小球从轨道上端 1、用改革开放的历史事实,说明中国共产党是如何坚持“与时俱进”思想的.2、如何理解坚持马克思主义指导思想与繁荣社会主义文化之间的关系.3、科学发展观“以人为本,全面协调可持续发 辩题:“青年成才的关键是自身能力还是外部机遇”?我是外部机遇,大家有没有新颖一点的想法?老辩题了,但是我想辩出新意,我是二遍或者三遍,重点是想要一些尖锐的问题,能够让对方无言以 扦插时,保留有芽和幼叶的插条比较容易生根成活,这主要是因为芽和幼叶能A.迅速生长 B.进行光合作用C.产生生长素 D.储存较多的有机物 有一道政治题,关于人民的概念,邓小平说:“我是中国人民的儿子,我深深地爱着我的祖国和人民.”这里的人民包括:①工农联盟 ②知识分子 ③社会主义事业的劳动者和建设者 ④拥护社会主 实验证明,带芽的枝条扦插时易成活,其主要原因 A带芽的枝条生长快B枝条易生根C枝条是活的D枝条进行光合作用快~~~~` 请帮忙说明每一项的理由,B) 多用途红光激光对位仪是什么多用途红光激光对位仪 He has a pink flower.就pink flower提问 答案是What's he has?还是What does he have 手为什么会发出骨头的 声音 电场碰到磁场会互相干扰吗? 扦插枝条芽越多越容易生根吗 为什么超越光速可以到达未来?我知道不能到达过去.因为结果不能出现在起因之前.看霍金的明白的.但是没弄懂他怎么就到未来了.实在不了解.求解释. 回答I'm sorry I don't have the video tape you have选以下哪个?A:No trouble at allB:Don't worry about itC:It's most kind of you. 横波探伤时,有时会出现因波型转换,产生变型纵波引起的波,这如何缺陷波相区分啊?请这方面的高手多多指导, 4.右图中的虚线与北半球中纬地区低压的的槽线.如果槽线东北端的气压低于西南端,则槽线西北和东南的风向 电焊机作业对现场仪表的干扰主要是电场干扰还是磁场干扰?仪表的单端接地,在现场好还是在控制室好? 电场能量问题:能量去哪里了?情况1:一个平行板电容器,带电为Q,不接电源导线等,开始介质为真空,电容为C.于是电场能量 W1 = Q^2 / 2C.接着插入一块介质板,假设其厚度正好是极板间距.于是后 北半球有一气压系统,其气流方向为顺时针方向,那会怎么样?A:夏季一般出现在大陆内部 B:是一个低气压区C:温带海洋性气候 D:亚热带季风气候 有一种电子元件既怕电场干扰又怕磁场干扰请你设计出一种能使该元件正常工作的保证方案. 关于时间达到光速的问题假如时间静止是速度达到光速的时候 那为什么不是其他比光还慢的速度 比如每天我开一辆跑得很快的车 那时间就会缓慢了吗 在北半球,当船舶自东向西通过气旋,观测到的风向顺时针方向变化时,则其气压变化趋势为? “cooking”是什么意思? 电场本身有能量吗?不是指电势能 关于A、B气压系统的叙述,正确的是? cooking是什么意思啊 太阳光斜射到平面镜上,会在墙上产生一个明亮的光斑,而阳光射到教室的地面上则不会产生光斑前者是由于光产生了____反射,后者是由于光产生了_____反射 为什么人听到自己发出的声音是骨传导,不是声带振动,然后周围的骨头在哪里呢?中间隔着空气么? cooking的意思这是英语作业,帮帮忙. 在半径为R1的导体球外套一个与它同心的导体球壳,球壳的内外半径分别为R2和R3,球与球壳之间是空气,球壳外也是空气,当球带电荷为Q时,这个系统储存的电场能量为多少?如果用导线把球与球壳 头转动是骨头发出很大声音是怎么回事 cooking什么意思? 水盆放在太阳下,映在墙上的光斑为什么会摇动? 在洪峰,洪量频率计算中,洪峰流量的选样采用?时段洪量采用? 洪峰流量中p=5%是指什么意思? 超声波的加湿器的换能片能用白米醋清洗吗?具体的步骤是什么?我用水加白米醋泡着运行了一天多,结果就不喷雾了,不知为什么原因. cooking中文意思 为什么遥感技术不能监测 洪峰流量? 为什么水盆放在太阳下映在墙上的光斑会摇动 cooking the lunch的中文意思 同一河道上下游谁的洪峰流量大要上下游之间没有水库或拦河坝的情况下 超声波加湿器换能片被腐蚀,使用时候是否会产生有害物质?不知道是被什么腐蚀的,估计不是精油就是盐水,请问继续使用的话,是否会产生有害物质危害健康? Cooking Healthy Foods in a Hurry中文意思 莫泊桑 项链怎么分段 分段的意思是什么 超声波能转换为可听音 关于身上一动骨头出声的情况我算是个大网虫了吧,熬夜情况蛮严重的,最近一直在家里,一般网前面一坐6 7 个小时以上这半年很长了,前段时间身子开始酸,但是生懒腰或者拉伸的时候就感受到 项链 莫泊桑中的所有人物分析及分段. 澳大利亚一墓园将举行”恐怖”派对 迎冯小刚好莱坞星光大道留手印 成内地导李克强:中德交流合作给双方带来实实在俄罗斯期待格鲁吉亚新政权对俄友好“美丽中国”图片展在莫斯科举行英国遭遇“飓风级”风暴 已造成至少两美国工业生产9月环比增长0.6%空客呼吁采用经济舱座椅宽度新标准部分城市难完成房价控制目标 四季度楼大学教授称北京房价会涨到每平方米80西班牙外交部召见美国大使 要求其解释\"鞠躬人\"亮相朝韩边界 寓意鞠躬欧盟称将向叙利亚提供8500万欧元人西班牙称监听行为无法接受 敦促美国提韩国陆军前方哨所士兵中枪身亡 军方展卜拉希米抵达叙利亚开始斡旋叙利亚问题联合特使卜拉希米抵达大马士西班牙称监听行为无法接受 敦促美国提袁隆平:终极目标水稻亩产1200公斤曝福建闽侯抽调教师协助拆迁 官方称已多国对美国监听表达不满要求解释 研究《走近科学》:靠谱防蚊法希望多来南京比赛,最爱小龙虾商务印书馆出了本《吃货辞典》美妙的奇遇深足三外援再次拒赴客场累得倒头就睡,想家的时间都没有NBA得分王杜兰特宣布退出美国男篮8月14日 星期四产业资本减持 市场比较纠结NBA得分王杜兰特宣布退出美国男篮与交警对视后居然驾车逃窜江苏医疗专家表示大部伤员伤势乐观明城墙开放 青春圣火“剪彩”住院病人走失溺亡 医院要承担赔偿责任范小青新作隐喻现代人迷失症谁是法甲金靴 博彩公司挺伊布中石化化工销售江苏分公司党委书记涉嫌8月15日 星期五首单落地,企业在线理财破冰深足三外援再次拒赴客场网信办要求加速推政务微信公号
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘