精华内容
下载资源
问答
  • 您已经回答了自己的问题,即下划线表示PyTorch中的就地操作...除非在沉重的内存压力下工作,否则在大多数情况下,不使用就地操作会更有效率.https://pytorch.org/docs/stable/notes/autograd.html#in-place-operations-...

    您已经回答了自己的问题,即下划线表示PyTorch中的就地操作.但是,我想简要指出为什么就地操作会出现问题:

    >首先,在大多数情况下,建议在PyTorch网站上不要使用就地操作.除非在沉重的内存压力下工作,否则在大多数情况下,不使用就地操作会更有效率.

    https://pytorch.org/docs/stable/notes/autograd.html#in-place-operations-with-autograd

    >其次,在使用就地操作时可能会出现计算梯度的问题:

    Every tensor keeps a version counter, that is incremented every time

    it is marked dirty in any operation. When a Function saves any tensors

    for backward, a version counter of their containing Tensor is saved as

    well. Once you access self.saved_tensors it is checked, and if it is

    greater than the saved value an error is raised. This ensures that if

    you’re using in-place functions and not seeing any errors, you can be

    sure that the computed gradients are correct.

    07001

    这是从您发布的答案中摘录并经过稍微修改的示例:

    首先是就地版本:

    import torch

    a = torch.tensor([2, 4, 6], requires_grad=True, dtype=torch.float)

    adding_tensor = torch.rand(3)

    b = a.add_(adding_tensor)

    c = torch.sum(b)

    c.backward()

    print(c.grad_fn)

    导致此错误:

    ---------------------------------------------------------------------------

    RuntimeError Traceback (most recent call last)

    in

    2 a = torch.tensor([2, 4, 6], requires_grad=True, dtype=torch.float)

    3 adding_tensor = torch.rand(3)

    ----> 4 b = a.add_(adding_tensor)

    5 c = torch.sum(b)

    6 c.backward()

    RuntimeError: a leaf Variable that requires grad has been used in an in-place operation.

    其次,非就地版本:

    import torch

    a = torch.tensor([2, 4, 6], requires_grad=True, dtype=torch.float)

    adding_tensor = torch.rand(3)

    b = a.add(adding_tensor)

    c = torch.sum(b)

    c.backward()

    print(c.grad_fn)

    哪个工作得很好-输出:

    因此,作为总结,我只想指出要在PyTorch中谨慎使用就地操作.

    展开全文
  • 另外,无论怎样升级硬件资源,单台服务器的资源(CPU、磁盘、内存、网络IO、事务数、连接数)总是有限的,最终数据库所能承载的数据量、数据处理能力都将遭遇瓶颈。分表、分库和读写分离可以有效地减小单台数据库的...

    f62c6d26d87793eb9d2ed002b4e186d2.png

    1.前言

    随着业务的发展,MySQL数据库中的表会越来越多,表中的数据量也会越来越大,相应地,数据操作的开销也会越来越大;另外,无论怎样升级硬件资源,单台服务器的资源(CPU、磁盘、内存、网络IO、事务数、连接数)总是有限的,最终数据库所能承载的数据量、数据处理能力都将遭遇瓶颈。

    分表、分库和读写分离可以有效地减小单台数据库的压力。

    本文主要针对业界主流的数据库中间件的实现、功能、成本等方面进行对比,总结数据库中间件的实现方式,并展望未来的可能发展。

    2. 实现方式

    一般来说,对于数据库中间件,可以在以下六个层次做切入。

    e959a3963e4ef2d4af86f8c3a95a3914.png

    2.1 代码层

    在同一个项目中创建多个数据源,采用if else的方式,直接根据条件在代码中路由。

    Spring中有动态切换数据源的抽象类,具体参见AbstractRoutingDataSource。

    如果项目不是很庞大,使用这种方式能够快速的进行分库。但缺点也是显而易见的,这种海量的代码侵入是绝不能被接受的。

    而且当查询结果返回时,需要对跨库、聚合等查询结果进行归并,开发工作量非常巨大。

    这种方式了解一下即可,一般不会去使用。

    2.2 框架层

    主要是修改或增强现有ORM框架的功能,在SQL中增加一些自定义原语或者hint来实现。

    常见的比如实现一些拦截器(比如Mybatis的Interceptor接口),增加一些自定义解析来控制数据的流向,效果虽然较好,但会改变一些现有的编程经验。

    这种情况适合公司ORM框架统一的情况,但在很多情况下不太现实。

    而且大部分情况下要修改框架源码,因此,也不推荐。

    2.3 驱动层

    无论是从代码层还是框架层做处理,都是高侵入、难维护的。

    因此,常见的数据库中间件,至少需要从驱动层开始,我们可以理解为一个smart-client。

    什么意思是smart-client呢?

    通常smart-client是在连接池或者driver的基础上进行了一层封装。

    这个smart-client内部可以与不同的数据库建立连接。

    服务需要查询的sql,就交给smart-client进行解析、优化,然后发送给具体的数据库进行操作。

    例如在读写分离情况下,smart-client会选择sql走从库还是主库;在分库分表的情况下,进行sql解析、sql改写等操作,然后路由到不同的分库,将得到的结果进行合并,返回给应用。

    8efabe82828e873b557299e2ee1d652e.png

    我们熟知的TDDL、Sharding-JDBC等,都是在此层切入。

    优点:

    1)实现方便,业务无入侵。smart-client不需要实现客户端通信协议,只需要在数据数据库厂商提供的不同语言的数据库驱动上做封装即可。例如mysql针对java语言提供了mysql-connector-java驱动,针对python提供了mysql-connector-python驱动。

    2)天然去中心化。smart-client以sdk的方式被应用引入,然后部署到不同的服务节点上,不需要有代理层proxy。因此相较于代理方式而言,不需要考虑高可用的问题。只要应用的节点没有全部宕机,就可以访问数据库。(这里的高可用是相比代理层proxy而言,数据库本身的高可用还是需要保证的)

    缺点:

    1)通常仅支持某一种语言。例如tddl、zebra、sharding-jdbc都是使用java语言开发,因此对于使用其他语言的用户,就无法使用这些中间件。如果其他语言要使用,那么就要开发多语言客户端。

    2)版本升级困难。因为应用使用数据源代理就是引入一个jar包的依赖,在有多个应用都对某个版本的jar包产生依赖时,一旦这个版本有bug,所有的应用都需要升级。而数据库代理升级则相对容易,因为服务是单独部署的,只要升级这个代理服务器,所有连接到这个代理的应用自然也就相当于都升级了。

    3)去中心化的缺点,比如无法做全局的sql限流

    2.4 代理层

    在应用中,我们通过一个普通的数据源(c3p0、druid、dbcp等)与代理服务器建立连接,所有的sql操作语句都是发送给这个代理,由这个代理去操作底层数据库,得到结果并返回给应用。在这种方案下,分库分表和读写分离的逻辑对开发人员是完全透明的。

    bc0026e4b67bfa46932ee37d819bd4ba.png

    像MySQL Router、MyCat、ShardingSphere(proxy模式)等,都是在此层切入。

    优点:

    1)多语言支持。也就是说,不论你用的php、java或是其他语言,都可以支持。以mysql数据库为例,如果proxy本身实现了mysql的通信协议,那么你可以就将其看成一个mysql 服务器,因此不同语言的开发者都可以使用mysql官方提供的对应的驱动来与这个代理服务器建通信。

    2)对业务开发同学透明。由于可以把proxy当成mysql服务器,理论上业务同学不需要进行太多代码改造,既可以完成接入。

    缺点:

    1)实现复杂。因为proxy需要实现被代理的数据库server端的通信协议,实现难度较大。

    2)proxy本身需要保证高可用。由于应用本来是直接访问数据库,现在改成了访问proxy,意味着proxy必须保证高可用。否则,数据库没有宕机,proxy挂了,导致数据库无法正常访问,就尴尬了。

    3)租户隔离。可能有多个应用访问proxy代理的底层数据库,必然会对proxy自身的内存、网络、cpu等产生资源竞争,proxy需要需要具备隔离的能力。

    2.5 Sidecar

    Sharding-Sidecar是ShardingSphere的第三个产品,目前仍然在规划中。 定位为Kubernetes或Mesos的云原生数据库代理,以DaemonSet的形式代理所有对数据库的访问。

    通过无中心、零侵入的方案提供与数据库交互的的啮合层,即Database Mesh,又可称数据网格。 Database Mesh的关注重点在于如何将分布式的数据访问应用与数据库有机串联起来,它更加关注的是交互,是将杂乱无章的应用与数据库之间的交互有效的梳理。使用Database Mesh,访问数据库的应用和数据库终将形成一个巨大的网格体系,应用和数据库只需在网格体系中对号入座即可,它们都是被啮合层所治理的对象。

    96f816c3c48215c7f1ccbb628d669c5b.png

    优点:

    分布式云原生的数据库中间件模式,集成了jdbc和proxy各自的优点,能满足高可用、跨语言、无感知升级等多种优势特性

    缺点:

    需要整体架构支持云原生体系

    目前还没正式上线。

    2.6 存储层

    这个层次实际上不应该叫数据库中间件了,需要更换存储。

    比如Aurora、polardb、tidb等分布式数据库,通过计算节点和存储节点分离,计算节点scale up,存储节点scale out的理念将公有云的关系数据库产品推向了一个新的高度。

    这样一来,实际上已经不再需要传统的数据库中间件了,一切问题天然就不存在了。

    3. 功能对比

    从上文可以了解到,目前最主流的数据库中间件主要是从驱动层smart-client和代理层proxy切入的。

    下面,我们来了解下业界主流的中间件产品在这两个层次的站队情况与实现的功能对比。

    7d4b55d99733b01235b40cea34670584.png

    其他还有比如:

    Atlas、Kingshard、DBProxy、mysql router、MaxScale、58 Oceanus、ArkProxy、Ctrip DAL、Tsharding、Youtube vitess、网易DDB、Heisenberg、proxysql、Mango、DDAL、Datahekr、MTAtlas、

    我们可以看到,基本各个大厂都撸过一遍自己的中间件产品。不过目前开源而且比较火的已经不多了,主要还是以shardingsphere为主。

    我们从功能维度,来对比一下几个产品。

    2b2a6fb6ca8df3eb12b139bd7dd6bb3a.png

    4. 展望

    从上文的分析可以看出,尽管目前主流的数据库中间件还是在smart-client和proxy两个层面进行处理的,但是,已经能看到未来的方向了。云原生的到来,估计会做进一步的降维打击。

    一方面是作为sidecar的模式,可能会有一个新的阶段,比如shardingsphere推出sidecar模式后。

    而另一方面,云数据库通过全新的计算存储分离的架构方式,打破传统关系型数据库的性能瓶颈,传统数据库中间件将不再需要关注,一切都将以数据库基础设施的形式提供给使用者。

    都看到最后了,原创不易,点个关注,点个赞吧~
    知识碎片重新梳理,构建Java知识图谱:https://github.com/saigu/JavaKnowledgeGraph (历史文章查阅非常方便)
    扫码关注我的公众号“阿丸笔记”,第一时间获取最新更新。同时能免费获取海量Java技术栈电子书、各个大厂面试题哦。

    dcd95373221a14802a2779fa5071fe3a.png
    展开全文
  • 另外,无论怎样升级硬件资源,单台服务器的资源(CPU、磁盘、内存、网络IO、事务数、连接数)总是有限的,最终数据库所能承载的数据量、数据处理能力都将遭遇瓶颈。分表、分库和读写分离可以有效地减小单台数据库的...

    c4e4ae19a1487bd3dfbf8d661a977466.gif

    62922a26b110d7bb62db4d2f9c2d28d1.png

    来源 | 阿丸笔记

    封图| CSDN 下载于视觉中国

    806ff48689b6808f6af6835013b153f7.png

    前言

    随着业务的发展,MySQL数据库中的表会越来越多,表中的数据量也会越来越大,相应地,数据操作的开销也会越来越大;另外,无论怎样升级硬件资源,单台服务器的资源(CPU、磁盘、内存、网络IO、事务数、连接数)总是有限的,最终数据库所能承载的数据量、数据处理能力都将遭遇瓶颈。

    分表、分库和读写分离可以有效地减小单台数据库的压力。

    而数据库中间件,也火了很长一段时间,基本上每个大厂都会自研一套。

    本文主要针对业界主流的数据库中间件的实现、功能、成本等方面进行对比,总结数据库中间件的实现方式,并展望未来的可能发展。

    d5840fc58f7af176eed675b6372fb580.png

    实现方式

    一般来说,对于数据库中间件,可以在以下六个层次做切入。

    6a4b1d3ec1a0ec8463a4db90b1239522.png

    2.1 代码层

    在同一个项目中创建多个数据源,采用if else的方式,直接根据条件在代码中路由。

    Spring中有动态切换数据源的抽象类,具体参见AbstractRoutingDataSource。

    如果项目不是很庞大,使用这种方式能够快速的进行分库。但缺点也是显而易见的,这种海量的代码侵入是绝不能被接受的。

    而且当查询结果返回时,需要对跨库、聚合等查询结果进行归并,开发工作量非常巨大。

    这种方式了解一下即可,一般不会去使用。

    2.2 框架层

    主要是修改或增强现有ORM框架的功能,在SQL中增加一些自定义原语或者hint来实现。

    常见的比如实现一些拦截器(比如Mybatis的Interceptor接口),增加一些自定义解析来控制数据的流向,效果虽然较好,但会改变一些现有的编程经验。

    这种情况适合公司ORM框架统一的情况,但在很多情况下不太现实。

    而且大部分情况下要修改框架源码,因此,也不推荐。

    2.3 驱动层

    无论是从代码层还是框架层做处理,都是高侵入、难维护的。

    因此,常见的数据库中间件,至少需要从驱动层开始,我们可以理解为一个smart-client。

    什么意思是smart-client呢?

    通常smart-client是在连接池或者driver的基础上进行了一层封装。

    这个smart-client内部可以与不同的数据库建立连接。

    服务需要查询的sql,就交给smart-client进行解析、优化,然后发送给具体的数据库进行操作。

    例如在读写分离情况下,smart-client会选择sql走从库还是主库;在分库分表的情况下,进行sql解析、sql改写等操作,然后路由到不同的分库,将得到的结果进行合并,返回给应用。

    8b50fcd0775c2f9873a47f01b399eaa5.png

    我们熟知的TDDL、Sharding-JDBC等,都是在此层切入。

    优点:

    1)实现方便,业务无入侵。smart-client不需要实现客户端通信协议,只需要在数据数据库厂商提供的不同语言的数据库驱动上做封装即可。例如mysql针对java语言提供了mysql-connector-java驱动,针对python提供了mysql-connector-python驱动。

    2)天然去中心化。smart-client以sdk的方式被应用引入,然后部署到不同的服务节点上,不需要有代理层proxy。因此相较于代理方式而言,不需要考虑高可用的问题。只要应用的节点没有全部宕机,就可以访问数据库。(这里的高可用是相比代理层proxy而言,数据库本身的高可用还是需要保证的)

    缺点:

    1)通常仅支持某一种语言。例如tddl、zebra、sharding-jdbc都是使用java语言开发,因此对于使用其他语言的用户,就无法使用这些中间件。如果其他语言要使用,那么就要开发多语言客户端。

    2)版本升级困难。因为应用使用数据源代理就是引入一个jar包的依赖,在有多个应用都对某个版本的jar包产生依赖时,一旦这个版本有bug,所有的应用都需要升级。而数据库代理升级则相对容易,因为服务是单独部署的,只要升级这个代理服务器,所有连接到这个代理的应用自然也就相当于都升级了。

    3)去中心化的缺点,比如无法做全局的sql限流

    2.4 代理层

    在应用中,我们通过一个普通的数据源(c3p0、druid、dbcp等)与代理服务器建立连接,所有的sql操作语句都是发送给这个代理,由这个代理去操作底层数据库,得到结果并返回给应用。在这种方案下,分库分表和读写分离的逻辑对开发人员是完全透明的。

    c941d08a3f5c368b995061c55e3b20c5.png

    像MySQL Router、MyCat、ShardingSphere(proxy模式)等,都是在此层切入。

    优点:

    1)多语言支持。也就是说,不论你用的php、java或是其他语言,都可以支持。以mysql数据库为例,如果proxy本身实现了mysql的通信协议,那么你可以就将其看成一个mysql 服务器,因此不同语言的开发者都可以使用mysql官方提供的对应的驱动来与这个代理服务器建通信。

    2)对业务开发同学透明。由于可以把proxy当成mysql服务器,理论上业务同学不需要进行太多代码改造,既可以完成接入。

    缺点:

    1)实现复杂。因为proxy需要实现被代理的数据库server端的通信协议,实现难度较大。

    2)proxy本身需要保证高可用。由于应用本来是直接访问数据库,现在改成了访问proxy,意味着proxy必须保证高可用。否则,数据库没有宕机,proxy挂了,导致数据库无法正常访问,就尴尬了。

    3)租户隔离。可能有多个应用访问proxy代理的底层数据库,必然会对proxy自身的内存、网络、cpu等产生资源竞争,proxy需要需要具备隔离的能力。

    2.5 Sidecar

    Sharding-Sidecar是ShardingSphere的第三个产品,目前仍然在规划中。定位为Kubernetes或Mesos的云原生数据库代理,以DaemonSet的形式代理所有对数据库的访问。

    通过无中心、零侵入的方案提供与数据库交互的的啮合层,即Database Mesh,又可称数据网格。Database Mesh的关注重点在于如何将分布式的数据访问应用与数据库有机串联起来,它更加关注的是交互,是将杂乱无章的应用与数据库之间的交互有效的梳理。使用Database Mesh,访问数据库的应用和数据库终将形成一个巨大的网格体系,应用和数据库只需在网格体系中对号入座即可,它们都是被啮合层所治理的对象。

    e05d798975722c8020c37c0ecc1ec4cb.png

    优点:

    分布式云原生的数据库中间件模式,集成了jdbc和proxy各自的优点,能满足高可用、跨语言、无感知升级等多种优势特性

    缺点:

    需要整体架构支持云原生体系

    目前还没正式上线。

    2.6 存储层

    这个层次实际上不应该叫数据库中间件了,需要更换存储。

    比如Aurora、polardb、tidb等分布式数据库,通过计算节点和存储节点分离,计算节点scale up,存储节点scale out的理念将公有云的关系数据库产品推向了一个新的高度。

    这样一来,实际上已经不再需要传统的数据库中间件了,一切问题天然就不存在了。4cb2ad83a5971c4d23124e93479bc819.png功能对比

    从上文可以了解到,目前最主流的数据库中间件主要是从驱动层smart-client和代理层proxy切入的。

    下面,我们来了解下业界主流的中间件产品在这两个层次的站队情况与实现的功能对比。

    4c188d411cab28c08b7fd096f6a783db.png

    其他还有比如:

    Atlas、Kingshard、DBProxy、mysql router、MaxScale、58 Oceanus、ArkProxy、Ctrip DAL、Tsharding、Youtube vitess、网易DDB、Heisenberg、proxysql、Mango、DDAL、Datahekr、MTAtlas、

    我们可以看到,基本各个大厂都撸过一遍自己的中间件产品。不过目前开源而且比较火的已经不多了,主要还是以shardingsphere为主。

    我们从功能维度,来对比一下几个产品。

    04b3920d568bdda673c5f74ca4499281.png

    b30b696bd5c88da863133830130180f0.png展望

    从上文的分析可以看出,尽管目前主流的数据库中间件还是在smart-client和proxy两个层面进行处理的,但是,已经能看到未来的方向了。云原生的到来,数据库中间件也会拥抱变化。

    一方面是作为sidecar的模式,可能会有一个新的阶段,比如shardingsphere推出sidecar模式后。

    而另一方面,云数据库通过全新的计算存储分离的架构方式,打破传统关系型数据库的性能瓶颈,传统数据库中间件将不再需要关注,一切都将以数据库基础设施的形式提供给使用者。

    aad610a1e338a69fbdf05e7b5c9177cb.png

    5da5795d5eca22f8bc7bb0f11171fb2c.png
    推荐阅读:
    还不知道 AWS 是什么?这 11 个重点带你认识 AWS !数据库连接池的原理没你想得这么复杂为什么程序员如此“嫌弃”主干开发模式?智能合约编写之 Solidity 的设计模式

    2020年,5种将死的编程语言

    我去,同事居然用明文存储密码!!!

    真香,朕在看了!
    展开全文
  • Memcached内存缓存技术

    2017-09-17 15:26:00
    Memcached是什么,有什么作用? Memcached是一个开源的、高性能的内存缓存软件,从名称上看Mem就是内存意思,而Cache就是缓存的意思。 Memcached通过在事先规划好的内存空间中临时缓存数据库中的各类数据,以...

    Memcached是什么,有什么作用?

    Memcached是一个开源的、高性能的内存缓存软件,从名称上看Mem就是内存的意思,而Cache就是缓存的意思。
    Memcached通过在事先规划好的内存空间中临时缓存数据库中的各类数据,以减少业务直接对数据库的访问,从而减轻数据库的访问压力和网站集群的响应速度。

    Memcached服务在企业集群架构中应用场景

    1.作为数据库的前端缓存应用

    完整缓存(易):例如商品分类,以及商品信息,可实现放到内存里,然后再对外提供数据访问。这个被称之为预热。用户访问时可以只读取memcached缓存,不读取数据库了。

    热点缓存(难):需要前端程序配合。只缓存热点的数据,即缓存经常被访问的数据。先预热基础数据,然后再动态更新。程序先读取缓存,如果缓存里没有对应的数据,程序再去读取数据库,然后程序把读到的数据放入缓存。

    特殊说明:
    如果碰到电商秒杀等高并发的业务,一定要事先预热,或者其他思想实现,例如:秒杀只是获取资格,而不是瞬间秒杀到手商品。如果数据更新,要同时触发缓存更新,防止给用户过过期数据。

    2.作为集群的session会话共享存储

    优点:速度比files块,可以解决共用session问题
    缺点:不能持久化,只能单点部署,多点数据无法同步,即使用hash分配节点,也会有session丢失

     Memcached服务在不同企业业务应用场景中的工作流程

    1.当web程序需要访问后端数据库获取数据时会优先访问Memcached内存缓存,如果缓存中有数据就直接获取返回前端服务及用户,如果没有数据(未命中),再由程序请求后端的数据库服务器,获取到对应的数据后,除了返回给前端服务及用户数据外,还会把数据放到Memcached内存中进行缓存,等待下次被访问。Memcahced内存始终是数据库的挡箭牌,从而大大的减轻数据库的访问压力,提高整个网站架构的响应速度,提升了用户体验。

    2.当程序更新,修改或删除数据库中已有的数据时,会同时发送请求通知Memcached已经缓存过的同一个ID内容的旧数据失效,从而保证Memcahce中的数据和数据库中的数据保持一致。如果是在高并发场合,除了通知Memcached过期的缓存失效外,还会通过相关机制,使得在用户访问新数据前,通过程序预先把更新过的数据推送到memcached中缓存起来,这样可以减少数据库的访问压力,提升memcached中缓存的命中率。

    3.数据库插件可以在写入更新数据库后,自动抛给MC缓存起来,自身不Cache

    Memcached服务分布式集群如何实现?

    1.程序端实现

    程序加载所有mc的ip列表,通过对key做hash(一致性哈希),从而映射到某一台mc,相同的key永远映射到同一台的mc。 Hash就是将任意长度的输入转化成固定长度的输出。
    一致性哈希的目的:不但保证每个对象只请求一个对应的服务器,同时保证当某个节点宕机,缓存服务器的更新重新分配比例降到最低。
    2.负载均衡器实现:由负载均衡器来做hash
     
    特殊说明:memcached集群和web服务集群是不一样的,所有memcached数据总和才是数据库的数据。每台memcached只有一部分数据。

    Memcached服务特点及工作原理是什么?

    a.节点之间相互独立
    b.数据是以key/value对形式存在的
    c.C/S模式架构,C语言编写,总共代码2000多行
    d.异步I/O模型,使用libevent事件通知机制
    e.全部数据放入内存,无持久性设计,重启服务数据丢失  (缺点)
    f.当内存中缓存的数据容量达到启动时设定的内存值时,自动使用LRU算法删除过期的缓存数据
    g.可以对存储的数据设置过期时间,这样过期后数据自动被清除,服务本身不会监控过期,而是在访问的时候查看key的时间戳判断是否过期
    h.memcached内存分配机制是对特定的内存进行分块,再把多个块分为组

    Memcached内存管理机制原理

    malloc的全称是memory allocation,中文叫动态内存分配,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存。
    早期的memcached内存管理方式是通过malloc分配的内存,使用完后通过free来回收内存。这种方式容易产生内存碎片并降低操作系统对内存的管理效率。加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached进程本身还慢,为了解决上述问题,Slab Allocator内存分配机制就产生了
    现在的memcached就是利用Slab Allocation机制来分配和管理内存。
    Slab Allocation机制原理是按照预先规定的大小,将分配给memcached的内存分割成特定长度的内存块chunk,再把尺寸相同的内存块分成组(chunks slab class),这些内存块不会释放,可以重复利用。

    Memcached服务器端中保存着slab class中空闲chunk个数的列表,根据该列表选择chunk,然后将数据缓存于其中。当有数据存入时,Memcached根据接收到的数据大小,分配一个能存下这个数据的最小内存块chunk。但是缺点在于由于分配的chunk大小是固定的,所以会有部分空间被浪费。

    避免浪费的办法是,预先计算出应用存入的数据大小或把同一业务类型的数据存入一个Memcached服务器中,确保存入的数据大小相对均匀。同时使用-f<factor> chunk size growth factor增长因子来划分chunk大小,进行调优。各组之间chunk的大小按照factor对应倍数递增,factor的默认值是1.25。

    同时slab allocator还有重复使用已分配的chunk的作用。也就是说,分配到的chunk不会释放,而是重复利用,用新数据替换旧数据。

    Slab主要术语:
    Page:分配给Slab的内存空间
    Chunk:内存块
    Slab Class:多个特定大小的chunk组成的组,一般也叫slabs

    Memcached的删除原理与删除机制

    Memcached主要的删除机制是LRU(最近最少用)算法,加上item过期失效。当您存数据到memcached中,可以指定该数据在缓存中可以呆多久。如果memcached内存不够用,过期的数据会优先被替换,接着轮到最老的未被使用的数据。在某些情况下(完整缓存),如果不想用LRU算法,可以通过-M参数启动Memcached,这样memcached内存耗尽也不会删除,宁愿报错也不删除。

    Memcached服务端与客户端的安装部署与使用测试

    #安装memcached前需要安装libevent
    yum install libevent-devel nc -y
    #源码安装memcahced
    cd /server/tools
    wget http://memcached.org/files/memcached-1.4.24.tar.gz
    tar xf memcached-1.4.24.tar.gz
    cd memcached-1.4.24
    ./configure --prefix=/application/memcached-1.4.24
    make
    make install
    ln -s /application/memcached-1.4.24/ /application/memcached
    
    #启动一个Mem实例
    /application/memcached/bin/memcached -m 16m -p 11211 -d -u root -c 8192 # 分配的内存 端口 后台 用户 最大并发连接数
    lsof -i :11211
    ps -ef | grep memcached | grep -v grep
    root       2984      1  0 23:10 ?        00:00:00 /application/memcached/bin/memcached -m 16m -p 11211 -d -u root -c 8192
    
    #可以启动多个Mem实例
    /application/memcached/bin/memcached -m 16m -p 11212 -d -u root -c 8192
    ps -ef | grep memcached | grep -v grep
    root       2984      1  0 23:10 ?        00:00:00 /application/memcached/bin/memcached -m 16m -p 11211 -d -u root -c 8192
    root       3036      1  0 23:16 ?        00:00:00 /application/memcached/bin/memcached -m 16m -p 11212 -d -u root -c 8192
     
    #加入开机启动
    echo "/application/memcached/bin/memcached -m 16m -p 11211 -d -u root -c 8192" >> /etc/rc.local
    echo "/application/memcached/bin/memcached -m 16m -p 11212 -d -u root -c 8192" >> /etc/rc.local
    
    #测试服务端是否正常
    [root@nagios tools]# printf "set key1 0 0 5\r\npeter\r\n" | nc 127.0.0.1 11211
    STORED
    [root@nagios tools]# printf "get key1\r\n" | nc 127.0.0.1 11211
    VALUE key1 0 5
    peter
    END
    [root@nagios tools]# printf "delete key1\r\n" | nc 127.0.0.1 11211
    DELETED
    
    #客户端php插件memcache安装
    cd /server/tools/
    wget http://pecl.php.net/get/memcache-2.2.7.tgz
    tar xf memcache-2.2.7.tgz
    cd memcache-2.2.7
    /application/php/bin/phpize
    ./configure --enable-memcache --with-php-config=/application/php/bin/php-config
    make
    make install
    Installing shared extensions:     /application/php-5.3.27/lib/php/extensions/no-debug-non-zts-20090626/
    ls -l /application/php-5.3.27/lib/php/extensions/no-debug-non-zts-20090626/
    total 244
    -rwxr-xr-x 1 root root 246696 Sep  1 22:51 memcache.so
    
    vim /application/php/lib/php.ini
    
    ; http://php.net/extension-dir
     extension_dir = "/application/php-5.3.27/lib/php/extensions/no-debug-non-zts-20090626/"
     extension=memcache.so
    
    /application/php/sbin/php-fpm -t
    pkill php-fpm
    /application/php/sbin/php-fpm
    ps -ef | grep php-fpm
    
    #http://10.0.0.23/test_info.php
    

     

    #连接测试
    vim op_mem.php
    <?php
            $memcache = new Memcache;
            $memcache->connect('172.16.1.23',11211) or die ("Could not connect Mc server");
            $memcache->set('key','oldboy book');
            $get=$memcache->get('key');
            echo $get;
    ?>
    
    /application/php/bin/php op_mem.php
    oldboy book
    

     如何实现集群中的session共享存储?

    vim /application/php/lib/php.ini
    
    1458 [Session]
    1459 ; Handler used to store/retrieve data.
    1460 ; http://php.net/session.save-handler
    1461 session.save_handler = memcache           #修改session存储方式
    1462
    1463 ; Argument passed to save_handler.  In the case of files, this is the path
    1464 ; where data files are stored. Note: Windows users have to change this
    1465 ; variable in order to use PHP's session functions.
    1466 ;
    1467 ; The path can be defined as:
    1468 ;
    1469 session.save_path = "tcp://172.16.1.23:11211"    #修改session存储路径
           
    pkill php-fpm
    /application/php/sbin/php-fpm
    
    #http://10.0.0.23/test_info.php
    

     

    session同步的多种方式

    a. lb层可以做会话保持,例如:
         lvs -p
         nginx ip_hash
         haproxy cookie insert
         PHP,JAVA都可以用
    b. 软件层,可以做session复制,例如
         tomcat resin couchbase
    c. session共享
          memcache或者其他nosql工具,PHP常用这个
    d. 高并发场景:例如门户网站用cookies或cookies配合session把用户级会话信息缓存在用户本地。高并发的场景cookies的效率比session要好很多

     MEMCACHED服务的状态信息的获取,例如:命中率

    1.通过memcache命令
    printf "stats\r\n" | nc 127.0.0.1 11211     #Memcached各种状态信息
    STAT pid 41346                              #PID
    STAT uptime 4759                            #服务已运行秒数
    STAT time 1505572559                        #服务当前UNIX时间戳
    STAT version 1.4.24                         #Memcached版本
    STAT libevent 1.4.13-stable                 #libevent版本
    STAT pointer_size 64                        #操作系统指针大小
    STAT rusage_user 0.121981                   #进程累计用户时间
    STAT rusage_system 0.112982                 #进程累计系统时间
    STAT curr_connections 10                    #当前连接数
    STAT total_connections 14                   #服务运行以来总连接数
    STAT connection_structures 11               #服务分配的连接结构数量
    STAT reserved_fds 20                        #内部使用的FD数
    STAT cmd_get 1                              #get请求次数
    STAT cmd_set 1                              #set请求次数
    STAT cmd_flush 0                            #flush请求次数
    STAT cmd_touch 0                            #touch请求次数
    STAT get_hits 1                             #get命中次数
    STAT get_misses 0                           #get未命中次数
    STAT delete_misses 0                        #delete未命中次数
    STAT delete_hits 1                          #delete命中次数
    STAT incr_misses 0                          #incr未命中次数
    STAT incr_hits 0                            #incr命中次数
    STAT decr_misses 0                          #decr未命中次数
    STAT decr_hits 0                            #decr命中次数
    STAT cas_misses 0                           #cas未命中次数
    STAT cas_hits 0                             #cas命中次数
    STAT cas_badval 0                           #cas使用擦拭次数
    STAT touch_hits 0                           #touch命中次数
    STAT touch_misses 0                         #touch未命中次数
    STAT auth_cmds 0                            #认证命令处理次数
    STAT auth_errors 0                          #认证命令失败次数
    STAT bytes_read 53                          #读取总字节数
    STAT bytes_written 45                       #写入总字节数
    STAT limit_maxbytes 16777216                #分配内存总大小(字节)
    STAT accepting_conns 1                      #接受新的连接
    STAT listen_disabled_num 0                  #失效的监听数
    STAT threads 4                              #当前线程数
    STAT conn_yields 0                          #连接操作主动放弃数目
    STAT hash_power_level 16                    #hash表等级
    STAT hash_bytes 524288                      #hash表大小
    STAT hash_is_expanding 0                    #hash表正在扩展
    STAT malloc_fails 0                         #分配内存失败的数目
    STAT bytes 0                                #已过期但未获取的对象数目
    STAT curr_items 0                           #当前的对象数目
    STAT total_items 1                          #当前存储占用的字节数
    STAT expired_unfetched 0                    #已过期但未获取的对象数目
    STAT evicted_unfetched 0                    #已驱逐但未获取的对象数目
    STAT evictions 0                            #LRU释放的对象数目
    STAT reclaimed 0                            
    STAT crawler_reclaimed 0                    
    STAT crawler_items_checked 0                    
    STAT lrutail_reflocked 0
    END
    
    [root@nagios ~]# printf "stats settings\r\n" | nc 127.0.0.1 11211     #Memcached设置信息
    [root@nagios ~]# printf "stats slabs\r\n" | nc 127.0.0.1 11211        #查看slabs相关信息
    [root@nagios ~]# printf "stats items\r\n" | nc 127.0.0.1 11211        #查看items相关信息
    [root@nagios ~]# printf "stats sizes\r\n" | nc 127.0.0.1 11211        #查看items的大小和个数
    [root@nagios ~]# printf "stats reset\r\n" | nc 127.0.0.1 11211        #清理统计数据
    
    #访问测试
    [root@nagios nginx]# printf "stats\r\n" | nc 127.0.0.1 11211 | grep get
    STAT cmd_get 1
    STAT get_hits 1
    STAT get_misses 0
    
    [root@nagios nginx]# printf "get key1\r\n" | nc 127.0.0.1 11211
    END
    
    [root@nagios nginx]# printf "stats\r\n" | nc 127.0.0.1 11211 | grep get
    STAT cmd_get 2
    STAT get_hits 1
    STAT get_misses 1
    

    2.通过Memcached管理工具Memadmin展示

    #Memadmin是基于PHP和JQuery的Memcached管理监控工具
    cd /server/tools
    wget http://www.junopen.com/memadmin/memadmin-1.0.12.tar.gz
    tar xf memadmin-1.0.12.tar.gz
    mv memadmin /application/nginx/html/www/
    
    #http://10.0.0.88/memadmin
    

     

    通过Nagios监控Memcached

    1.监控指标:

    端口

    命名率

    响应时间

    模拟用户存取

    2.Nagios插件开发

    #模拟用户进行存取,测试memcached的状态
    vim check_mc.sh
    [ $# -ne 2 ] && {
         echo "$0 ip port"
         exit
    }
    #!/bin/bash
    ServerIP=$1
    ServerPort=$2
    cmd="nc $ServerIP $ServerPort"
    printf "delete key\r\n" | $cmd > /dev/null 2>&1
    sleep 1
    printf "set key 0 0 5\r\npeter\r\n" | $cmd > /dev/null 2>&1
    if [ `printf "get key\r\n" | $cmd | grep peter | wc -l` -eq 1 ];then
        echo "mc is alive."
        exit 0
    else
        echo "mc is dead."
        exit 2
    fi
    
    [root@nagios ~]# sh check_mc.sh 127.0.0.1 11211
    mc is alive.
    

     

     

    转载于:https://www.cnblogs.com/Peter2014/p/7535733.html

    展开全文
  • 谢邀QPS的全称Query per Second,意思是每秒的查询...为什么要设置ramp-up period呢,为了让系统的执行测试前可以“热身”,比如内存交换区、上下文、CDN 文件缓存等。ramp-up period和 QPS 其实不冲突的概念...
  • 通过这些指标,可以判断出系统的当前内存使用压力以及GC压力内存分配是否合理 2.jstat常见命令有哪些? jstat -gc [PID] [PID]指的进程编号 返回的结果和代表的意思是: S0C:这S0区的大小 S0U:这S0区当前...
  • ehcache

    2016-12-15 13:18:52
    今天在学习 : 不知道是什么意思?找了一些相关的记录下,方便以后查询:引自:http://www.blogjava.net/i369/articles/219407.html 1.EhCache是什么  EhCache是Hibernate的二级缓存技术之一,可以把查询...
  • 文章来源极客时间课程笔记 ...AOF 日志正好相反,它写后日志,“写后”的意思是 Redis 先执行命令,把数据写入内存,然后才记录日志. 为什么是是写后日志? 为了避免额外的检查开销,Redis 在向 AOF 里面记录日
  • 如果一个进程占用内存超过了这个内存限制,就会报OOM的问题,很多涉及到大图片的频繁操作或者需要读取一大段数据在内存中使用时,很容易报OOM的问题。... 什么是多进程? 多进程就是多个进程的意思
  • Android多进程

    2017-05-09 00:04:32
    如果一个进程占用内存超过了这个内存限制,就会报OOM的问题,很多涉及到大图片的频繁操作或者需要读取一大段数据在内存中使用时,很容易报OOM的问题。... 什么是多进程? 多进程就是多个进程的意思
  • EhCache二级缓存技术

    千次阅读 2009-08-02 21:11:00
    今天在学习 : 不知道是什么意思?找了一些相关的记录下,方便以后查询:引自:http://www.blogjava.net/i369/articles/219407.html 1.EhCache是什么 EhCache是Hibernate的二级缓存技术之一,可以把查询出来的数据...
  • PHP中的Memcache详解

    2021-01-21 16:05:29
    由于它的工作机制内存中开辟一块空间,然后建立一个HashTable,Memcached管理这些HashTable,所以速度非常快。 二、Memcache和memcached的区别 为什么会有Memcache和memcached两种名称?其实Memcache这个项目...
  • golang Map和指针优化

    2019-12-19 16:27:19
    小编不啰嗦,直接上代码: 执行结果: 这里的内存分配容量和次数都为0,因为此次定义的数据量较小,...原因:值传递,传入过去会分配两个内存空间,意思是内存会分配两个容量存储。 而直接使用指针的话,可以直接...
  • 3.SpringBoot+Redis

    2019-02-10 10:18:04
    说明:这一篇系列文章,需要前几篇的基础才比较容易理解,或者已经对 Maven和idea比较熟悉的读者阅读。...其次,redis一种 nosql数据库 ( 以键值对来存储数据 ): not only sql 的意思。 在特...
  • Redis基础

    2020-03-30 20:34:05
    一款开源key-value型内存数据库。常用于做缓存,能够减轻数据库的压力,高可用且支持高并发,性能非常高。 Redis的实际应用 token生成、session共享、分布式锁、自增id 基本数据类型 String set key value get ...
  • 缓冲写数据的意思是在数据需要更新时不马上把数据存到数据库,而是先缓冲一下,然后在适当的时机再写入到数据库中。 缓冲写数据可以避免在网站并发访问多的时候,数据库瞬间承受过大压力,而造成死锁或响应不及时的...
  • 疯狂的程序员

    热门讨论 2012-07-18 18:05:32
    程序员是什么?他不知道。他问:“程序员能找到教书的工作吗?” “当然,一点问题都没有。随便哪个学校都能教。想我那个年代,这城市有多少程序员,数都能数出来。我还报了高程,唉……差一点。” 能去教书当然好,...
  • 你的意思是 [code="java"] for(int i = start; i (list.size() - limit) > 0 ? limit : list.size(); i++) { // then return these results ? } [/code] 这是内存分页的做法.. 定义了baseParams:{start:...
  • Node.js关于Stream的理解

    2020-12-08 19:35:53
    而2是什么意思呢。其实是差不多意思,只是数据的处理在第一次触发readable事件时,通过while循环读取数据,直到数据读取完成返回null。即在第一次触发readable就完成了数据的读取。后面几次触发的...

空空如也

空空如也

1 2
收藏数 21
精华内容 8
关键字:

内存压力是什么意思