精华内容
下载资源
问答
  • 分页实现的原理

    千次阅读 2018-12-20 15:49:17
    什么是分页技术 分页,是一种将所有数据分段展示给用户的技术.用户每次看到的不是全部数据,而是其中的一部分,如果在其中没有找到自习自己想要的内容,用户可以通过制定页码或是翻页的方式转换可见内容,直到找到自己想...
    什么是分页技术

    分页,是一种将所有数据分段展示给用户的技术.用户每次看到的不是全部数据,而是其中的一部分,如果在其中没有找到自习自己想要的内容,用户可以通过制定页码或是翻页的方式转换可见内容,直到找到自己想要的内容为止.其实这和我们阅读书籍很类似

    分页的意义

    分页确实有效,但它一定会加大系统的复杂度,但可否不分页呢?如果数据量少的话当然可以.但是对于企业信息系统来说数据量不会限制在一个小范围内.如果不顾一切的Select * from某个表,再将返回的数据一古脑的扔给客户,即使客户能够忍受成千上万足够让人眼花缭乱的表格式数据,繁忙的网络,紧张的服务器也会提出它们无声的抗议,甚至有时会以彻底的罢工作为终结

    从请求发起到返回数据的整个过程

    现在你已经下定决心想要分页了,在动手书写代码之前,先让我们回想一下,在典型的三层架构中,从请求发起到返回数据的整个过程.如下所示:
    在这里插入图片描述

    分页的实现

    用户发起请求,后他查询数据库返回所有的条数,并且返回用户所需要的数据,比方说用户请求的是第一页(page = 1),用户设置的第一页的数据显示条数为50条(limit=50),那么后台查询满足条件的数据,并且返回前50条给用户显示,此时用户看到的就是第一页的50条数据,加入用户请求的是第二页的数据,那么传给后台page为2,显示条数limit为50后台查询的就是符合条件的51-100条数据返回给用户

    展开全文
  • Android Binder机制原理

    2021-12-02 16:59:15
    一 Android与Linux通信机制的比较 虽然Android继承使用Linux的内核,但Linux与Android的通信机制不同。 在Linux中使用的IPC通信机制如下: 1.管道(Pipe):点对点通信,因为采用存储转发方式,需要拷贝2次数据,...

    一 Android与Linux通信机制的比较

    虽然Android继承使用Linux的内核,但Linux与Android的通信机制不同。
    在Linux中使用的IPC通信机制如下:
    1.管道(Pipe):点对点通信,因为采用存储转发方式,需要拷贝2次数据,效率低下
    2.Socket:是一个通用的接口,通常用于网络请求,但是建立连接和断开连接开销太大,效率低下
    3.共享内存:虽然在传输时没有拷贝数据,但其控制机制复杂(比如跨进程通信时,需获取对方进程的pid,得多种机制协同操作)。因为内存共享,数据很容易被一方篡改,所以安全性不高

    android的binder通信:
    性能方面
    在移动设备上(性能受限制的设备,比如要省电),广泛地使用跨进程通信对通信机制的性能有严格的要求,Binder相对出传统的Socket方式,更加高效。Binder数据拷贝只需要一次,而管道、消息队列、Socket都需要2次,共享内存方式一次内存拷贝都不需要,但实现方式又比较复杂。
    安全方面
    首先传统IPC的接收方无法获得对方进程可靠的UID和PID(用户ID进程ID),从而无法鉴别对方身份。Android为每个安装好的应用程序分配了自己的UID,故进程的UID是鉴别进程身份的重要标志。其实Binder机制主要是在本机内进行跨进程通信,而socket等IPC方式主要是用于跨网络的通信手段,因而socket不能限制了入口和出口,所以从使用场景来看,socket给用户提供的使用范围更广,而binder由于为了保证它的数据安全性,必须限制于android系统的机子中,而且在内核中就已经对UID进行了验证。

    二 Binder机制原理

    2.1 虚拟内存

    我们知道以前程序直接访问和操作的都是物理内存;这样做有很大弊端,首先不能进行多进程运行,试想一下:你必须执行完一条指令后才能接着执行下一条,如果是多进程的话,由于直接操作物理内存地址,当一个进程给内存地址1000赋值后,另一个进程也同样给内存地址赋值,那么第二个进程对内存的赋值会覆盖第一个进程所赋的值,这回造成两条进程同时崩溃。这时候就抽象一个概念叫虚拟内存:每个进程都有自己独立的逻辑地址空间,然后这个空间以“页”为单位,将连续的地址空间分开,对于进程来看,逻辑上貌似有很多内存空间,其中一部分对应物理内存上的一块(称为页框,通常页和页框大小相等),还有一些没加载在内存中的对应在硬盘上。那么虚拟内存和物理内存如何实现映射呢?是通过一个叫MMU(内存管理单元),MMU里面主要负责两件事:1.记录该页是否在物理内存中运行 2.记录该页空间在物理内存哪里运行 。如果虚拟内存的页并不存在于物理内存中,会产生缺页中断,从磁盘中取得缺的页放入内存,如果内存已满,还会根据某种算法将磁盘中的页换出。
    这样通过引入虚拟空间的概念,就能让物理内存充分的利用,同时利用各个进程逻辑地址分页运行的特性,实现多进程运行也不是难事

    2.2 用户空间和内核空间

    我们上面已经知道了虚拟内存的由来;每个进程可以拥有4GB的虚拟内存。Linux内核将这4GB的空间分为两个部分。最高的1GB(从虚拟地址0xC0000000到0xFFFFFFFF)供内核使用,称为“内核空间“。而较低的3GB(从虚拟地址0x00000000到0xBFFFFFFF),供各个进程使用,称为“用户空间”,因为每个进程可以通过系统调用进入内核,因此,Linux内核空间由系统内的所有进程共享。所以,每个进程可以拥有4GB的虚拟地址空间(也叫虚拟内存)。每个进程有各自的私有用户空间(0~3GB),这个空间对系统中的其他进程是不可见的。最高的1GB内核空间则为所有进程以及内核所共享(虽然共享,但是一个完整的虚拟地址空间就是4GB,内核空间是每个进程都要被分配的,只是他们对应相同的地址空间)。
    在这里插入图片描述

    2.3 原理

    2.3.1 隔离

    为了保护进程空间不被别的进程破坏或者干扰,Linux的进程是相互独立的(进程隔离),而且一个进程空间还分为用户空间和内核(Kernel)空间,相当于把Kernel和上层的应用程序抽像的隔离开。这里有两个隔离,一个进程间是相互隔离的,二是进程内有用户和内核的隔离。

    2.3.2 组成

    Binder框架定义了四个角色:Server,Client,ServiceManager以及Binder驱动。其中Server,Client,ServiceManager运行于用户空间,驱动运行于内核空间。这四个角色的关系类似:Server是服务器,Client是客户终端,ServiceManager是服务注册中心(类似房屋中介)。
    在这里插入图片描述
    要进行Client-Server之间的通信,从面向对象的角度,在Server内部有一个Binder实体,在Client内部有一个Binder对象的引用,其实就是Binder的一个代理,Client通过对Binder引用间接的操作Server内部的Binder实体,这样就实现了通信。

    但是现在的问题是会有很多个提供不同服务的Server(比如有媒体播放服务,音视频捕获服务等),而且会有很多Client(比如多个应用都要调用媒体播放服务),那么我们怎么才能够实现正确的Client调用正确的Server呢?就好比房客怎么才能够租到自己想要租的房子(联系上房东),这个时候中介就起到重要作用,房东想要出租自己的房子就必须要到中介注册,房客想要租房子就要去中介那里找,同样的道理,这里Client就是房客,Server就是房东,ServiceManager就是房屋中介,每个Server如果要提供服务就必须要去ServiceManager那里去注册,ServiceManager在一张查找表中记录一个Server的名字,对应着Server的引用。Client想要获得Server,必须通过名字到ServiceManager取找Server的引用,获得这个Server的binder引用,通过这个binder引用去和Server通信。

    2.3.3 宏观分析

    在这里插入图片描述

    Binder 驱动:
    Binder 驱动就如同路由器一样,是整个通信的核心;驱动负责进程之间 Binder 通信的建立,Binder 在进程之间的传递,Binder 引用计数管理,数据包在进程之间的传递和交互等一系列底层支持。
    可以说是Client,Server,ServerManager之间沟通的桥梁

    ServiceManager 与实名 Binder(Server)**
    ServiceManager 和 DNS 类似,作用是将字符形式的 Binder 名字转化成 Client 中对该Binder 的引用,使得 Client 能够通过 Binder 的名字获得对 Binder 实体的引用。注册了名字的 Binder 叫实名 Binder,就像网站一样除了除了有 IP 地址以外还有自己的网址。Server创建了 Binder,并为它起一个字符形式,可读易记得名字,将这个 Binder 实体连同名字一起以数据包的形式通过 Binder 驱动发送给 ServiceManager ,通知 ServiceManager 注册一个名为“张三”的 Binder,它位于某个 Server 中。驱动为这个穿越进程边界的 Binder 创建位于内核中的实体节点以及 ServiceManager 对实体的引用,将名字以及新建的引用打包传给 ServiceManager。ServiceManger 收到数据后从中取出名字和引用填入查找表。细心的读者可能会发现,ServierManager 是一个进程,Server 是另一个进程,Server 向ServiceManager 中注册 Binder 必然涉及到进程间通信。当前实现进程间通信又要用到进程间通信,这就好像蛋可以孵出鸡的前提却是要先找只鸡下蛋!Binder 的实现比较巧妙,就是预先创造一只鸡来下蛋。ServiceManager 和其他进程同样采用 Bidner 通信,ServiceManager 是 Server 端,有自己的 Binder 实体,其他进程都是 Client,需要通过这个 Binder 的引用来实现 Binder 的注册,查询和获取。ServiceManager 提供的 Binder 比较特殊,它没有名字也不需要注册。当一个进程使用 BINDERSETCONTEXT_MGR 命令将自己注册成 ServiceManager 时 Binder 驱动会自动为它创建 Binder 实体(这就是那只预先造好的那只鸡)。其次这个 Binder 实体的引用在所有 Client 中都固定为 0 而无需通过其它手段获得。也就是说,一个 Server 想要向 ServiceManager 注册自己的 Binder 就必须通过这个0 号引用和 ServiceManager 的 Binder 通信。类比互联网,0 号引用就好比是域名服务器的地址,你必须预先动态或者手工配置好。要注意的是,这里说的 Client 是相对于ServiceManager 而言的,一个进程或者应用程序可能是提供服务的 Server,但对于ServiceManager 来说它仍然是个 Client。

    Client 获得实名 Binder 的引用
    Server 向 ServiceManager 中注册了 Binder 以后, Client 就能通过名字获得 Binder 的引用了。Client 也利用保留的 0 号引用向 ServiceManager 请求访问某个 Binder: 我申请访问名字叫张三的 Binder 引用。ServiceManager 收到这个请求后从请求数据包中取出 Binder名称,在查找表里找到对应的条目,取出对应的 Binder 引用作为回复发送给发起请求的Client。从面向对象的角度看,Server 中的 Binder 实体现在有两个引用:一个位于ServiceManager 中,一个位于发起请求的 Client 中。如果接下来有更多的 Client 请求该Binder,系统中就会有更多的引用指向该 Binder ,就像 Java 中一个对象有多个引用一样

    2.3.4 从内存角度分析

    • 进程空间划分:

    上面说过。进程之间的内存划分为各自进程的用户空间和内核空间;用户空间指的是用户程序所运行的空间,内核空间是 Linux 内核的运行空间,为了安全,它们是隔离的,即使用户的程序崩溃了,内核也不受影响。

    • 系统调用:

    用户态和内核态虽然从逻辑上进行了用户空间和内核空间的划分,但不可避免的用户空间需要访问内核资源,比如文件操作、访问网络等等。为了突破隔离限制,就需要借助系统调用来实现

    • 系统调用是用户空间访问内核空间的唯一方式
      保证了所有的资源访问都是在内核的控制下进行的,避免了用户程序对系统资源的越权访问,提升了系统安全性和稳定性。Linux 使用两级保护机制:0 级供系统内核使用,3 级供用户程序使用。当一个任务(进程)执行系统调用而陷入内核代码中执行时,称进程处于内核运行态(内核态)。此时处理器处于特权级最高的(0级)内核代码中执行。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每个进程都有自己的内核栈。当进程在执行用户自己的代码的时候,我们称其处于用户运行态(用户态)。此时处理器在特权级最低的(3级)用户代码中运行。系统调用主要通过如下两个函数来实现:copy_from_user() //将数据从用户空间拷贝到内核空间copy_to_user() //将数据从内核空间拷贝到用户空间2.2 Linux下的传统IPC通信原理
    copy_from_user() //将数据从用户空间拷贝到内核空间
    copy_to_user() //将数据从内核空间拷贝到用户空间
    

    Linux下的传统IPC通信原理

    在这里插入图片描述

    通常的做法是消息发送方将要发送的数据存放在内存缓存区中,通过系统调用进入内核态。然后内核程序在内核空间分配内存,开辟一块内核缓存区,调用 copyfromuser() 函数将数据从用户空间的内存缓存区拷贝到内核空间的内核缓存区中。同样的,接收方进程在接收数据时在自己的用户空间开辟一块内存缓存区,然后内核程序调用 copytouser() 函数将数据从内核缓存区拷贝到接收进程的内存缓存区。这样数据发送方进程和数据接收方进程就完成了一次数据传输,我们称完成了一次进程间通信。这种传统的 IPC 通信方式有两个问题:性能低下,一次数据传递需要经历:内存缓存区 --> 内核缓存区 --> 内存缓存区,需要 2 次数据拷贝;接收数据的缓存区由数据接收进程提供,但是接收进程并不知道需要多大的空间来存放将要传递过来的数据,因此只能开辟尽可能大的内存空间或者先调用 API 接收消息头来获取消息体的大小,这两种做法不是浪费空间就是浪费时间。

    Binder跨进程通信原理动态内核可加载模块 && 内存映射这个动态内核可加载模块,就是Binder驱动,运行在内核空间,使各个用户进程通过Binder实现通信。内存映射简单的讲就是将用户空间的一块内存区域映射到内核空间。映射关系建立后,用户对这块内存区域的修改可以直接反应到内核空间;反之内核空间对这段区域的修改也能直接反应到用户空间。内存映射能减少数据拷贝次数,实现用户空间和内核空间的高效互动。两个空间各自的修改能直接反映在映射的内存区域,从而被对方空间及时感知。也正因为如此,内存映射能够提供对进程间通信的支持。Binder涉及到的内存映射通过mmap()实现

    Binder实现原理
    在这里插入图片描述
    首先Binder驱动在内核空间创建一个数据接收缓存区;接着在内核空间开辟一块内存缓存区,建立内核缓冲区和内核中数据接收缓存缓存区之间的映射关系,以及内核中数据接收缓存区和接收进程用户空间地址的映射关系发送方通过系统调用copy from user()将数据copy到内核中的内核缓冲区,由于内核缓存区和接收进程的用户空间存在内存映射,因此也就相当于把数据发送到了接收进程的用户空间。

    三 Binder通信中的代理模式

    A 进程想要 B 进程中某个对象(object)是如何实现的呢?它们分属不同的进程,A 进程没法直接使用B 进程中的 object。

    前面我们介绍过跨进程通信的过程都有 Binder 驱动的参与,因此在数据流经 Binder 驱动的时候驱动会对数据做一层转换。当 A 进程想要获取 B 进程中的 object 时,驱动并不会真的把 object 返回给 A,而是返回了一个跟 object 看起来一模一样的代理对象 objectProxy,这个 objectProxy 具有和 object 一摸一样的方法,但是这些方法并没有 B 进程中 object 对象那些方法的能力,这些方法只需要把把请求参数交给驱动即可。对于 A 进程来说和直接调用 object 中的方法是一样的。当 Binder 驱动接收到 A 进程的消息后,发现这是个 objectProxy 就去查询自己维护的表单,一查发现这是 B 进程 object 的代理对象。于是就会去通知 B 进程调用 object 的方法,并要求 B 进程把返回结果发给自己。当驱动拿到 B 进程的返回结果后就会转发给 A 进程,一次通信就完成了。
    在这里插入图片描述

    展开全文
  • 文章目录分片机制存储原理分段存储段的优越点延迟策略段合并ES的性能优化ES存储设备ES内部索引优化调整ES参数JVM性能调优 分片机制 分片是Elasticsearch在集群中分发数据的关键 把分片想象成数据的容器,文档存储在分...

    分片机制

    分片是Elasticsearch在集群中分发数据的关键

    把分片想象成数据的容器,文档存储在分片中,然后分片分配到集群中的节点,当集群扩容或缩小,ES将会自动在节点间迁移分片,以使集群保持平衡一个分片在es中是最小级别的工作单元.它只是保存了索引中所数据的一部分

    分片可以是主分片或者复制分片,在集群中唯一一个空节点创建一个叫做blogs的索引,默认情况下,一个索引被分配5个主分片,每个主分片又分配一个副分片

    主分片

    在一个多分片的索引中写入数据时,通过路由来确定具体写入哪一个分片中,大致路由过程

    shard = hash(routing) % number_of_primary_shards

    路由规则: routing是一个可变值,默认存入文档的_id(可以设置自定义值),然后通过hash得到数字,这个数字在除以number_of_primary_shards(主分片数量),然后得到余数, 然后0 到number_of_primary_shards(主分片数量) 之间的余数,就是文档所在那个分片的位置

    这也就是为什么,创建索引的时候确定主分片的数量,并且永远不能再改变 这个数量了,因为数量改变了之前的路由规则也就变了,文档在根据之前的路由规则找,也找不到了

    索引中每个文旦都属于一个单独的主分片,所有主分片数量决定了索引最多能存储多少数据,实际数量取决于数据,硬件和应用场景

    副分片
    复制分片只是主分片的一个副本,它可以防止硬件故障导致的数据丢失,同时可以提供读请求,比如搜索或者从别的 shard 取回文档。

    每个主分片都有一个或多个副本分片,当主分片异常时,副本可以提供数据的查询等操作。主分片和对应的副本分片是不会在同一个节点上的,所以副本分片数的最大值是 n -1(其中 n 为节点数)。

    存储原理

    ES写入流程,这个流程最终是在ES的内存中执行的,数据被分配到特点分片和副本之后,最周存储在磁盘上,这样如果服务起突发断电也就不会丢失数据,具体的存储路径可在配置文件 …/config/elasticsearch.yml中进行设置,默认在安装目录的data文件下

    分段存储

    索引文档以段的形式存储在磁盘上
    什么是段:
    索引文件被拆分成多个子文件,则每个文件叫做段,每一个段都是一个倒排索引,并且段具有不变性,一旦索引的数据被写入磁盘,就不可再修改,Es底层采用分段的存储模式,使它在读写几乎避免了锁的出现,大大提升读写性能

    段被写入磁盘后会生成一个提交点.提交点是一个用来记录所有提交后段信息的文件,一个段如果拥有多个提交点,就说明这个段只有读的权限,相反,当段在内存中时,就是有写的权限,而不具备读数据库的权限,意味着不能被检索出来

    段的概念提出是因为:早起全文检索中的整个文档集合建立了一个很大的倒排索引,并将其写入磁盘中,如果索引有更新,就需要更新创建一个索引来替换之前的索引,这种方式效率很低,且每创建一次索引的成本很高,索引对数据的更新不能过于频繁,照成性能缓慢

    索引分段存储不可修改,那么 新增 更新和删除是怎么操作的呢

    1.新增: 由于数据是新的,只需对当前文档新增一个段就可以了

    2.删除:由于不可修改,所以对删除操作,不会把文档给移除掉,而是新增一个.del文件,文件中会列出这些被删除文档的段信息,这个被标记删除的文档仍然可以被查询匹配到,但它最终会在结果即返回前从结果集中移除

    3.更新:更新不会修改旧的段来进行文档更新, 其实更新相当于删除和新增两个动作组成 会将旧的文档在啊.del文件中标记删除, 新文档被索引到一个新的段中’

    段的优越点

    优点:

    1.不需要锁,如果你从来不更新索引,你就不需要担心多进程同时修改数据的问题
    2.一旦索引被读入内核的文件系统缓存,便会留在那里,由于其不变性,只要文件系统缓存中还有足够的空间,那么大部分读请求会直接请求到内存,而不会命中磁盘,从而提高了性能
    3.其他缓存.在索引的生命周期始终有效,他们不需要在每次数据改变时被重建,因为数据不会变化
    4.写入单个大的倒排序允许数据被压缩,减少磁盘I/O和需要被缓存到内存的索引使用量

    段的不变型缺点

    1.当对旧数据进行删除时,旧数据不会马上删除,而是在.del文件中被标记删除,而旧数据只能等到段更新时才能被移除,这样会照成大量的空间浪费
    2.若有一条数据频繁的更新,每次更新都是新增的标识旧的,则会有大量的空间浪费
    3.每次新增数据时都需要新增一个段来存储数据,当段的数量太多时,对服务器的资源例如文件局柄的消耗会非常大
    4.在查询的结果中包含所有的结果集,需要排除被标记删除的旧数据,这增加了查询的负担

    延迟策略

    Es为了提升写的性能,ES并没有每新增一条数据就增加一个段,而是采用了延迟写的策略

    写入内存的数据无法被检索出来,只有在新增数据时ES将其数据先写入内存中,在内存和磁盘时文件系统缓存,当达到默认的时间(1秒)或内存的数据达到一定量时,会触发一下刷新(Refresh),将内存中的数据生成到一个新的段上并缓存到文件缓存系统上,稍后再次被刷新到磁盘中并生成提交点

    虽然通过延时写的策略可以减少数据往磁盘上写的次数提升了整体的写入能力,但是我们知道文件缓存系统也是内存空间,属于操作系统的内存,只要是内存都存在断电或异常情况下丢失数据的危险。
    为了避免丢失数据,Elasticsearch添加了事务日志(Translog),事务日志记录了所有还没有持久化到磁盘的数据。添加了事务日志后整个写索引的流程如下图所示。

    在这里插入图片描述

    一个新文档被索引之后,先被写入到内存中,但是为了防止数据的丢失,会追加一份数据到事务日志中。不断有新的文档被写入到内存,同时也都会记录到事务日志中。这时新数据还不能被检索和查询。

    当达到默认的刷新时间或内存中的数据达到一定量后,会触发一次 refresh,将内存中的数据以一个新段形式刷新到文件缓存系统中并清空内存。这时虽然新段未被提交到磁盘,但是可以提供文档的检索功能且不能被修改。

    随着新文档索引不断被写入,当日志数据大小超过512M或者时间超过30分钟时,会触发一次 flush。内存中的数据被写入到一个新段同时被写入到文件缓存系统,文件系统缓存中数据通过 fsync 刷新到磁盘中,生成提交点,日志文件被删除,创建一个空的新日志。

    通过这种方式当断电或需要重启时,ES不仅要根据提交点去加载已经持久化过的段,还需要工具Translog里的记录,把未持久化的数据重新持久化到磁盘上,避免了数据丢失的可能。

    段合并

    由于自动刷新流程每秒会创建一个新的段 ,这样会导致短时间内的段数量暴增。而段数目太多会带来较大的麻烦。每一个段都会消耗文件句柄、内存和cpu运行周期。更重要的是,每个搜索请求都必须轮流检查每个段然后合并查询结果,所以段越多,搜索也就越慢。
    Elasticsearch通过在后台定期进行段合并来解决这个问题。小的段被合并到大的段,然后这些大的段再被合并到更大的段。段合并的时候会将那些旧的已删除文档从文件系统中清除。被删除的文档不会被拷贝到新的大段中。合并的过程中不会中断索引和搜索。

    在这里插入图片描述

    ES的性能优化

    ES存储设备

    磁盘在现代服务器上通常都是瓶颈。Elasticsearch 重度使用磁盘,你的磁盘能处理的吞吐量越大,你的节点就越稳定。这里有一些优化磁盘 I/O 的技巧:
    使用 SSD。就像其他地方提过的, 他们比机械磁盘优秀多了。

    使用 RAID 0。条带化 RAID 会提高磁盘 I/O,代价显然就是当一块硬盘故障时整个就故障了。不要使用镜像或者奇偶校验 RAID 因为副本已经提供了这个功能。

    另外,使用多块硬盘,并允许 Elasticsearch 通过多个 path.data 目录配置把数据条带化分配到它们上面。

    不要使用远程挂载的存储,比如 NFS 或者 SMB/CIFS。这个引入的延迟对性能来说完全是背道而驰的。
    如果你用的是 EC2,当心 EBS。即便是基于 SSD 的 EBS,通常也比本地实例的存储要慢

    ES内部索引优化

    在这里插入图片描述

    快速找到某个term,先将所有的term排个序,然后根据二分法查找term,时间复杂度为logN,就像通过字典查找一样,这就是Term Dictionary。现在再看起来,似乎和传统数据库通过B-Tree的方式类似。

    但是如果term太多,term dictionary也会很大,放内存不现实,于是有了Term Index,就像字典里的索引页一样,A开头的有哪些term,分别在哪页,可以理解term index是一颗树。这棵树不会包含所有的term,它包含的是term的一些前缀。通过term index可以快速地定位到term dictionary的某个offset,然后从这个位置再往后顺序查找。

    在内存中用FST方式压缩term index,FST以字节的方式存储所有的term,这种压缩方式可以有效的缩减存储空间,使得term index足以放进内存,但这种方式也会导致查找时需要更多的CPU资源。演示地址:Build your own FST

    对于存储在磁盘上的倒排表同样也采用了压缩技术减少存储所占用的空间,更多可以阅读 Frame of Reference and Roaring Bitmaps。

    调整ES参数

    给每个文档指定有序的具有压缩良好的序列模式ID,避免随机的UUID-4 这样的 ID,这样的ID压缩比很低,会明显拖慢 Lucene。
    对于那些不需要聚合和排序的索引字段禁用Doc values。Doc Values是有序的基于document => field value的映射列表;

    不需要做模糊检索的字段使用 keyword类型代替 text 类型,这样可以避免在建立索引前对这些文本进行分词。

    如果你的搜索结果不需要近实时的准确度,考虑把每个索引的 index.refreshinterval 改到 30s 。如果你是在做大批量导入,导入期间你可以通过设置这个值为 -1 关掉刷新,还可以通过设置 index.numberof_replicas: 0关闭副本。别忘记在完工的时候重新开启它。

    避免深度分页查询建议使用Scroll进行分页查询。普通分页查询时,会创建一个from + size的空优先队列,每个分片会返回from + size 条数据,默认只包含文档id和得分score给协调节点,如果有n个分片,则协调节点再对(from + size)× n 条数据进行二次排序,然后选择需要被取回的文档。当from很大时,排序过程会变得很沉重占用CPU资源严重。

    减少映射字段,只提供需要检索,聚合或排序的字段。其他字段可存在其他存储设备上,例如Hbase,在ES中得到结果后再去Hbase查询这些字段。

    创建索引和查询时指定路由routing值,这样可以精确到具体的分片查询,提升查询效率。路由的选择需要注意数据的分布均衡。

    JVM性能调优

    确保堆内存最小值( Xms )与最大值( Xmx )的大小是相同的,防止程序在运行时改变堆内存大小。Elasticsearch 默认安装后设置的堆内存是 1 GB。可通过 …/config/jvm.option文件进行配置,但是最好不要超过物理内存的50%和超过32GB。
    GC 默认采用CMS的方式,并发但是有STW的问题,可以考虑使用G1收集器。
    ES非常依赖文件系统缓存(Filesystem Cache),快速搜索。一般来说,应该至少确保物理上有一半的可用内存分配到文件系统缓存。

    参考文章

    展开全文
  • 1、文件上传原理将客户端的文件上传到服务器,再将服务器的临时文件上传到指定目录2、客户端配置提交表单表单的发送方式为post添加enctype="multipart/form-data"3、服务器端配置file_uploads = On,支持HTTP上传...

    1、文件上传原理

    将客户端的文件上传到服务器,再将服务器的临时文件上传到指定目录

    2、客户端配置

    提交表单

    表单的发送方式为post

    添加enctype="multipart/form-data"

    3、服务器端配置

    file_uploads = On,支持HTTP上传

    uoload_tmp_dir = ,临时文件保存目录

    upload_max_filesize = 2M,允许上传文件的最大值

    max_file_uploads = 20 ,允许一次上传到的最大文件数

    post_max_size = 8M,post方式发送数据的最大值

    max_execution_time = -1,设置了脚本被解析器终止之前允许的最大执行时间,单位为秒,防止程序写的不好而占尽服务器资源。-1代表无穷

    max_input_time = 60 ,脚本解析输入数据允许的最大时间,单位为秒

    max_input_nesting_level = 64 ,设置输入变量的嵌套深度

    max_input_vars_ = 1000,接受多少输入的变量(限制分别应用于$_GET、$_POST和$_COOKIE超全局变量,将会导致E_WARNING的产生,更多的输入变量将会从请求中截断。

    memory_limit = 128M,最大单线程的独立内存使用量。也就是一个web请求,给予线程最大的内存使用量的定义

    4、错误信息说明

    UPLOAD_ERR_OK:其值为0,没有错误发生,文件上传成功

    UPLOAD_ERR_INI_SIZE:其值为1,上传的文件超过了php.ini中upload_max_filesize选项限制的值

    UPLOAD_ERR_FORM_SIZE:其值为2,上传文件的大小超过了HTML表单中MAX_FILE_SIZE选项指定的值

    UPLOAD_ERR_PARTIAL:其值为3,文件只有部分被上传

    UPLOAD_ERR_NO_FILE:其值为4,没有文件被上传

    UPLOAD_ERR_NO_TMP_DIR:其值为6,找不到临时文件夹

    UPLOAD_ERR_CANT_WRITE:其值为7,文件写入失败

    UPLOAD_ERR_EXTENSION:其值为8,上传的文件被PHP扩展程序中断

    5、客户端限制

    通过表单隐藏域限制文件上传文件的最大值

    通过accept属性限制上传文件类型

    6、在客户端的限制,用户可在网页上修改代码后上传,故无实际意义。应在服务器端加以限制

    限制上传文件的大小

    限制上传文件类型

    检测是否为真实图片类型

    检测是否为HTTP POST方式上传

    7、完整代码如下:

    upload.php

    文件上传

    请选择要上传的文件:

    test.php

    header('content-type:text/html;charset=utf-8');

    include_once 'upload.func.php';

    //上传封装函数的五个参数:$fileInfo,$maxsize,$uploadPath,$allowExt,$flag

    $fileInfo=$_FILES['myFile'];

    // print_r($_FILES);

    // exit;

    // $filename=$_FILES['myFile']['name'];

    // $type=$_FILES['myFile']['type'];

    // $tmp_name=$_FILES['myFile']['tmp_name'];

    // $size=$_FILES['myFile']['size'];

    // $error=$_FILES['myFile']['error'];

    $maxsize=2097152;

    $uploadPath='uploads';

    $allowExt=array('jpeg','jpg','png','gif');

    $flag=true;

    $newName=uploadFile($fileInfo,$maxsize,$uploadPath,$allowExt,$flag);

    echo "上传成功,路径为:".$newName;

    ?>

    upload.func.php

    function uploadFile($fileInfo,$maxsize,$uploadPath,$allowExt,$flag){

    //判断错误号

    if($fileInfo['error']>0){

    switch ($fileInfo['error']){

    case '1':

    $mes="上传文件超过了PHP配置文件中upload_max_filesize选项的值";

    break;

    case '2':

    $mes="超过了表单MAX_FILE_SIZE限制的大小";

    break;

    case '3':

    $mes="文件部分被上传";

    break;

    case '4':

    $mes="没有选择上传文件";

    break;

    case '6':

    $mes="没有找到临时目录";

    break;

    case '7':

    case '8':

    $mes="系统错误";

    break;

    }

    exit($mes);

    }

    $ext=pathinfo($fileInfo['name'],PATHINFO_EXTENSION);

    //检测上传文件的类型

    if (!@in_array($ext,$allowExt)) {

    exit('非法文件类型');

    }

    //检测上传文件的大小是否符合规范

    //$maxsize=2097152;//默认值为2M

    if ($fileInfo['size']>$maxsize) {

    exit('上传文件超过'.($maxsize/1024/1024).'M');

    }

    //检测图片是否为真实图片类型,立flag,若不需要检测,则设置flag为false即可

    //$flag=true;

    if($flag){

    if (!@getimagesize($fileInfo['tmp_name'])) {

    exit('不是真实的图片类型');

    }

    }

    //检测文件是否通过HTTP POST方式上传的

    if (!@is_uploaded_file($fileInfo['tmp_name'])) {

    exit('文件不是通过HTTP POST方式上传的');

    }

    //存储目录

    if(!@file_exists($uploadPath)){

    mkdir($uploadPath,0777,true);

    chmod($uploadPath,0777);

    }

    $uniName=MD5(uniqid(microtime(true),true)).'.'.$ext;

    $destination=$uploadPath.'/'.$uniName;

    if (!@move_uploaded_file($fileInfo['tmp_name'], $destination)) {

    exit('文件上传失败');

    }

    //echo "文件上传成功";

    // return array{

    // 'newName'=>$destination;

    // 'size'=>$fileInfo['size'];

    // 'type'=>$fileInfo['type']

    // };

    return $destination;

    }

    ?>

    Struts2+Uploadify文件上传使用详解

    Uploadify是JQuery的一个上传插件,实现的效果非常不错,带进度显示.不过官方提供的实例是php版本的,本文将详细介绍Uploadify在java中的使用,您也可以点击下面的链接进行演示或下 ...

    Web应用安全之文件上传漏洞详解

    什么是文件上传漏洞 文件上传漏洞是在用户上传了一个可执行的脚本文件,本通过此脚本文件获得了执行服务器端命令的功能,这种攻击方式是最为直接,最为有效的,有时候,几乎没有什么门槛,也就是任何人都可以进行这 ...

    jquery组件WebUploader文件上传用法详解

    这篇文章主要为大家详细介绍了jquery组件WebUploader文件上传用法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 WebUploader是由Baidu WebFE(FEX)团队开发的一 ...

    FastDFS的配置、部署与API使用解读(8)FastDFS多种文件上传接口详解(转)

    1.StorageClient与StorageClient1的区别 相信使用happy_fish的FastDFS的童鞋们,一定都熟悉StorageClient了,或者你熟悉的是StorageClien ...

    ASP.Net大文件上传组件详解

    首先右键单击网站根目录,在弹出的快捷菜单中,选择"添加引用"菜单项,弹出"添加引用",切换到"浏览"找到组件的Dll文件"Best ...

    C# Socket-TCP异步编程原理详解附源码

    目录 目录异步原理主要方法源码Server源码:Client源码实验效果(广播为例)参考博客 TOC 异步原理 套接字编程原理:延续文件作用思想,打开-读写-关闭的模式. C/S编程模式如下: Ø 服 ...

    七牛云存储Python SDK使用教程 - 上传策略详解

    文 七牛云存储Python SDK使用教程 - 上传策略详解 七牛云存储 python-sdk 七牛云存储教程 jemygraw 2015年01月04日发布 推荐 1 推荐 收藏 2 收藏,2.7k  ...

    Spring Boot 文件上传原理

    首先我们要知道什么是Spring Boot,这里简单说一下,Spring Boot可以看作是一个框架中的框架--->集成了各种框架,像security.jpa.data.cloud等等,它无须关 ...

    补习系列(11)-springboot 文件上传原理

    目录 一.文件上传原理 二.springboot 文件机制 临时文件 定制配置 三.示例代码 A. 单文件上传 B. 多文件上传 C. 文件上传异常 D. Bean 配置 四.文件下载 小结 一.文件 ...

    随机推荐

    这些.NET开源项目你知道吗?.NET平台开源文档与报表处理组件集合(三)

    在前2篇文章这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧 和这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑)中,大伙热情高涨.再次拿出自己的私货,在.NET平台 ...

    FineUI Grid控件高度自适应

    引言 页面里使用f:Grid控件,添加分页功能,然后高度填充整个页面. 如何使用 使用FineUI 控件的每个页面都有一个f:PageManager控件,它包含属性:AutoSizePanelID,设 ...

    DB2常用sql函数 (转载)

    http://www.techonthenet.com/sql/index.php 一.字符转换函数 1.ASCII() 返回字符表达式最左端字符的ASCII 码值.在ASCII()函数中,纯数字的字 ...

    iOS沙盒(sandbox)

    iOS沙盒 每个ios应用都有自己的应用沙盒,应用沙盒就是文件系统目录,默认下iOS应用只能访问自己的沙盒 extenaion是iOS8新开放的一种对几个固定系统区域的扩展机制,它可以在一定程度上弥补 ...

    query attr prop区别

    大家都知道有的浏览器只要写disabled,checked就可以了,而有的要写成disabled = "disabled",checked="checked", ...

    Android TableLayout 常用的属性介绍及演示

    TableLayout经常用的属性是: 1.android:collapseColumns:以第0行为序,隐藏指定的列:把android:collapseColumns=0,2 意思是把第0和第2列隐 ...

    php这样实现伪静态

    mod_rewrite是Apache的一个非常强大的功能,它可以实现伪静态页面.下面我详细说说它的使用方法 1.检测Apache是否支持mod_rewrite 通过php提供的phpinfo()函数查 ...

    基于AFN封装的带缓存的网络请求

    给大家分享一个基于AFN封装的网络请求 git: https://github.com/zhouxihi/NVNetworking #带缓存机制的网络请求 各类请求有分带缓存 , 不带缓存, 可自定义 ...

    HTML DOM应用案例2

    day03
    展开全文
  • 如何重新加载Spring Boot上的更改,而无需重新启动服务器? Spring Boot中的监视器是什么? 如何在Spring Boot中禁用Actuator 端点安全性? 如何在自定义端口上运行Spring Boot 应用程序? 什么是YAML? 如何实现Spring ...
  • Linux I/O底层原理揭秘

    2021-03-10 21:23:30
    本文转载腾讯游戏工程师:Linux I/O底层原理全面揭秘 这里向作者致敬,写的非常棒,从技术背景到原理,通俗易懂。 摘要 从虚拟内存、I/O 缓冲区,用户态&内核态以及 I/O 模式等等知识点全面而又详尽地剖析 Linux...
  • 前言Elasticsearch 是一个实时的分布式搜索与分析引擎,在使用过程中,有一些典型的使用场景,比如分页、遍历等。在使用关系型数据库中,我们被告知要注意甚至被明确禁止使用深度分页,同...
  • 以便其他的项目可以调用 mvn clean deploy —— 运行清理和发布 5.Maven核心概念 Maven 能够实现自动化构建是和它的内部原理分不开的,这里我们从 Maven 的九个核心概念入手, 看看 Maven 是如何实现自动化构建的 ...
  • 今年由于疫情原因,SAP一年一度的DKOM(Developer Kick-Off Meeting)切换成了线上模式,刚刚于昨天圆满落幕。...这个incident是客户在使用SAP Spartacus并试图启用其服务器端渲染模式(Server Side Rendering
  • 操作系统原理 第2版

    2021-05-24 04:16:24
    图书简介本书全面系统地介绍...第7章简述现代操作系统的发展和安全保护机制。为强化操作系统课程的实践环节,附录A给出了8个实验指导,附录B和C分别给出Linux常用系统调用和常用命令,供教师和学生参考。本书可作为...
  • 操作系统实现原理

    2021-05-11 01:21:07
    实模式下的寄存器 2.1 实模式下内存寻址/分段机制 16位8086型号的cpu的寻址 2.2 实模式下的汇编指令讲解 mov数据传输指令 movs(b/w/d/x)系列集 用于字符串在内存中的拷贝需要搭配cld与std还有rep loop 循环指令 ...
  • 目录 1.Nginx介绍 1.1 什么是Nginx? 1.2Nginx能做什么 1.3 为什么要选择用Nginx 2.Nginx的安装与配置 2.1 Nginx 安装 ...3.Nginx工作原理 3.1 工作原理: 3.1.1 Nginx处理Request请求过程解析 ...
  • 不适合在服务器操作系统 内容精选换一换简要介绍Tornado是一个Python Web框架和异步网络库,最初由FriendFeed开发。 通过使用非阻塞网络I / O,Tornado可以扩展到成千上万的开放连接,非常适合长时间轮询,WebSocket...
  • 分库分表原理

    2021-02-04 13:38:12
    或者基于主从复制实现读写分离,让写的服务都访问 master 服务器,读的请求都访问从服务器,slave 服务器自动 master 主服务器同步数据。 或者在数据库前面加一层缓存,达到减少数据库的压力,提升访问速度的目的。...
  • kafka原理详解(一)

    2021-01-13 00:50:28
    Kafka为什么比其他的MQ都快,采用的是机制是顺序写入磁盘和Memory Mapped Files(内存映射文件)。顺序写入:每个partition都是一个文件,kafka会把收到的message插入到文件末尾,每个consumer...
  • 比较过滤器的API实现 通过RowFilter过滤rowkey比0003还要小的数据 @Test public void rowFilterStudy() throws IOException { Scan scan = new Scan(); //通过rowFilter实现数据按照rowkey进行过滤 ...
  • 反思 系列博客是我的一种新...虽然上述的三方播放器都自带完善的缓存功能,但对于内容和形式都日新月异的一众互联网产品来说,想要打造完美契合自家产品的用户体验,播放器自身的缓存机制已逐渐无法满足需求。 最具.
  • PHP的分页功能

    2021-04-22 16:09:37
    PHP的分页功能更新时间:2007年03月21日 00:00:00 作者://建立数据库连接$link=mysql_connect("localhost","root","wyh7ye");;//获取当前页数mysql_select_db("test",$link);if(isset($_GET[page]))...{$page=...
  • 这一篇的主题是「Linux C/C++ 服务器/后台开发学习路线」。 这样的文章相信大家都见得不少了,写之前也非常忐忑,能不能和其它人写得不一样, 也定下了一个目标,这篇文章,不能是简单的堆砌学习资源和书单推荐,更...
  • HBase的JavaAPI 创建maven项目,pom文件如下: <repositories> <repository> <id>cloudera</id> <url>https://repository.cloudera.com/artifactory/cloudera-repos/<...dep
  • 架构设计:介绍RocketMQ部署架构和技术架构。 设计原理:介绍RocketMQ关键机制的设计原理,主要包括消息存储、通信机制、消息过滤、负载均衡、事物消息等。
  • 大数据框架原理简介

    2020-12-29 20:59:03
    针对上篇文章遗留问题联邦学习之一 几亿级别的数据量架构如何设计且如何实现 ...Hadoop和关系数据库服务器之间传送数据 数据仓库 数据仓库是供战略决策使用的数据基本不更新的反应历史变化的数据DW:D
  • 提高服务器性能最简单粗暴的方式,就是增加机器和升级硬件配置。虽然现在的硬件越来越便宜,但是一味地通过增加机器来解决并发量的增长,成本是非常高昂的。结合技术优化方案,才是更有效的解决方法。一、we...
  • 我们知道cpu要频繁的响应中断,有些中断来了,cpu必须放下正在执行的进程去响应中断,比如对于web服务器网络流量很高的服务器,网络中断很频繁;操作系统提供一个亲和度算法将一个终端号绑定到一个核上。这样其他核...
  • 我们知道Redis的数据都存储在内存中,如果服务器突然宕机,那么内存数据将会全部消失,为了防止这种情况出现,利用一套机制来保证数据不会因为故障而丢失,我们将这种机制称之为Redis的持久化机制,该机制主要目的是...
  • 操作系统原理

    2021-06-02 21:39:13
    操作系统原理第一章第二章三级目录 第一章 计算机系统组成部分: 硬件 应用程序 操作系统 用户 操作系统的作用: 1.操作系统是管理计算机硬件的程序,为应用程序提供基础并充当计算机用户和计算机硬件的中介。 2....
  • 服务器搭建配置以及服务器开发相关 有用的参考链接 用亚马逊云建代理服务器 阿里云建站教程 阿里云用户指南 【node】阿里云node环境的搭建以及安全组的配置 使用SSH密钥对连接Linux实例 SSH连接下复制远程Linux...
  • TLB的作用及工作原理

    千次阅读 2020-12-20 04:18:47
    当前所有的个人桌面,笔记本和服务器处理器都使用TLB来进行虚拟地址到物理地址的映射。使用TLB内核可以快速的找到虚拟地址指向物理地址,而不需要请求RAM内存获取虚拟地址到物理地址的映射关系。这与data cache和...
  • 分页查询信息(使用jdbc连接mysql数据库实现分页查询任务) 分页查询信息 使用jdbc连接mysql数据库实现分页查询任务 通过mysql数据库提供的分页机制,实现商品信息的分页查询功能,将查询到的信息显示到jsp页面上....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 26,659
精华内容 10,663
关键字:

服务器分页机制原理