精华内容
下载资源
问答
  • 症状:越狱后系统空间占用巨大,系统-其他 空间近30G 解决办法: SSH到IOS,使用du -sh * 逐个排查目录大小, 最终定位到com.apple.CacheDeleteAppContainerCaches.deathrow 目录 目录说明: 此目录是appleid...

    环境:iOS 13.5 |  unc0ver

    症状:越狱后系统空间占用巨大,系统-其他 空间近30G

    解决办法: SSH到IOS,使用du -sh * 逐个排查目录大小,

                     最终定位到com.apple.CacheDeleteAppContainerCaches.deathrow 目录

     

    1.在cydia中安装openssh

    2.ssh到iPhone 默认账户root 密码alpine

    3.du -sh /private/var/mobile/Library/Caches/* 查看哪个目录较大

    4.定位到com.apple.CacheDeleteAppContainerCaches.deathrow

     

    目录说明: 此目录是appleid更换后,APP数据使用新ID数据,可以直接删除,亲测有效

     

     

     

     

    展开全文
  • 大型web系统数据缓存设计

    千次阅读 2016-09-18 09:21:52
    所以接下来将讨论一下应用系统缓存的设计方面应该注意哪些东西,包括缓存的选型、常见缓存系统的特点和数据指标、缓存对象结构设计和失效策略以及缓存对象的压缩等等,以期让有需求的同学尤其是初学者能够快速、系统...

    【IT168 技术】在高访问量的web系统中,缓存几乎是离不开的;但是一个适当、高效的缓存方案设计却并不容易;所以接下来将讨论一下应用系统缓存的设计方面应该注意哪些东西,包括缓存的选型、常见缓存系统的特点和数据指标、缓存对象结构设计和失效策略以及缓存对象的压缩等等,以期让有需求的同学尤其是初学者能够快速、系统的了解相关知识。

    大型web系统数据缓存设计

      数据库的瓶颈

      1 数据量

      关系型数据库的数据量是比较小的,以我们常用的MySQL为例,单表数据条数一般应该控制在2000w以内,如果业务很复杂的话,可能还要低一些。即便是对于Oracle这些大型商业数据库来讲,其能存储的数据量也很难满足一个拥有几千万甚至数亿用户的大型互联网系统。

      2 TPS

      在实际开发中我们经常会发现,关系型数据库在TPS上的瓶颈往往会比其他瓶颈更容易暴露出来,尤其对于大型web系统,由于每天大量的并发访问,对数据库的读写性能要求非常高;而传统的关系型数据库的处理能力确实捉襟见肘;以我们常用的MySQL数据库为例,常规情况下的TPS大概只有1500左右(各种极端场景下另当别论);下图是MySQL官方所给出的一份测试数据:

    大型web系统数据缓存设计

      而对于一个日均PV千万的大型网站来讲,每个PV所产生的数据库读写量可能要超出几倍,这种情况下,每天所有的数据读写请求量可能远超出关系型数据的处理能力,更别说在流量峰值的情况下了;所以我们必须要有高效的缓存手段来抵挡住大部分的数据请求!

      3 响应时间

      正常情况下,关系型数据的响应时间是相当不错的,一般在10ms以内甚至更短,尤其是在配置得当的情况下。但是就如前面所言,我们的需求是不一般的:当拥有几亿条数据,1wTPS的时候,响应时间也要在10ms以内,这几乎是任何一款关系型数据都无法做到的。

      那么这个问题如何解决呢?最简单有效的办法当然是缓存!

      缓存系统选型

      1 缓存的类型

      1.1 本地缓存

      本地缓存可能是大家用的最多的一种缓存方式了,不管是本地内存还是磁盘,其速度快,成本低,在有些场合非常有效;

      但是对于web系统的集群负载均衡结构来说,本地缓存使用起来就比较受限制,因为当数据库数据发生变化时,你没有一个简单有效的方法去更新本地缓存;然而,你如果在不同的服务器之间去同步本地缓存信息,由于缓存的低时效性和高访问量的影响,其成本和性能恐怕都是难以接受的。

      1.2 分布式缓存

      前面提到过,本地缓存的使用很容易让你的应用服务器带上“状态”,这种情况下,数据同步的开销会比较大;尤其是在集群环境中更是如此!

      分布式缓存这种东西存在的目的就是为了提供比RDB更高的TPS和扩展性,同时有帮你承担了数据同步的痛苦;优秀的分布式缓存系统有大家所熟知的Memcached、Redis(当然也许你把它看成是NoSQL,但是我个人更愿意把分布式缓存也看成是NoSQL),还有国内阿里自主开发的Tair等;

      对比关系型数据库和缓存存储,其在读和写性能上的差距可谓天壤之别;memcached单节点已经可以做到15w以上的tps、Redis、google的levelDB也有不菲的性能,而实现大规模集群后,性能可能会更高!

      所以,在技术和业务都可以接受的情况下,我们可以尽量把读写压力从数据库转移到缓存上,以保护看似强大,其实却很脆弱的关系型数据库。

      1.3 客户端缓存

      这块很容易被人忽略,客户端缓存主要是指基于客户端浏览器的缓存方式;由于浏览器本身的安全限制,web系统能在客户端所做的缓存方式非常有限,主要由以下几种:

      a、 浏览器cookie;这是使用最多的在客户端保存数据的方法,大家也都比较熟悉;

      b、 浏览器本地缓存;很多浏览器都提供了本地缓存的接口,但是由于各个浏览器的实现有差异,所以这种方式很少被使用;此类方案有chrome的Google Gear,IE的userData、火狐的sessionStorage和globalStorage等;

      c、 flash本地存储;这个也是平时比较常用的缓存方式;相较于cookie,flash缓存基本没有数量和体积的限制,而且由于基于flash插件,所以也不存在兼容性问题;不过在没有安装flash插件的浏览器上则无法使用;

      d、 html5的本地存储;鉴于html5越来越普及,再加上其本地存储功能比较强大,所以在将来的使用场景应该会越来越多。

      由于大部分的web应用都会尽量做到无状态,以方便线性扩容,所以我们能使用的除了后端存储(DB、NoSQL、分布式文件系统、CDN等)外,就只剩前端的客户端缓存了。

      对客户端存储的合理使用,原本每天几千万甚至上亿的接口调用,一下就可能降到了每天几百万甚至更少,而且即便是用户更换浏览器,或者缓存丢失需要重新访问服务器,由于随机性比较强,请求分散,给服务器的压力也很小!在此基础上,再加上合理的缓存过期时间,就可以在数据准确和性能上做一个很好的折衷。

      1.4 数据库缓存

      这里主要是指数据库的查询缓存,大部分数据库都是会提供,每种数据库的具体实现细节也会有所差异,不过基本的原理就是用查询语句的hash值做key,对结果集进行缓存;如果利用的好,可以很大的提高数据库的查询效率!数据库的其他一些缓存将在后边介绍。

      2 选型指标

      现在可供我们选择使用的(伪)分布式缓存系统不要太多,比如使用广泛的Memcached、最近炒得火热的Redis等;这里前面加个伪字,意思是想说,有些所谓的分布式缓存其实仍是以单机的思维去做的,不能算是真正的分布式缓存(你觉得只实现个主从复制能算分布式么?)。

      既然有这么多的系统可用,那么我们在选择的时候,就要有一定的标准和方法。只有有了标准,才能衡量一个系统时好时坏,或者适不适合,选择就基本有了方向。

      下边几点是我个人觉的应该考虑的几个点(其实大部分系统选型都是这么考虑的,并非只有缓存系统):

      2.1 容量

      废话,容量当然是越大越好了,这还用说么,有100G我干嘛还要用10G?其实这么说总要考虑一下成本啦,目前一台普通的PC Server内存128G已经算是大的了,再大的话不管是从硬件还是从软件方面,管理的成本都会增加。单机来讲,比如说主板的插槽数量,服务器散热、操作系统的内存分配、回收、碎片管理等等都会限制内存卡的容量;即便使用多机的话,大量内存的采购也是很费money的!

      有诗云:山不在高,有仙则名;所以内存也不在多,够用就好!每个系统在初期规划的时候,都会大致计算一下所要消耗的缓存空间,这主要取决于你要缓存的对象数量和单个对象的大小。一般来说,你可以采用对象属性在内存中的存储长度简单加和的方法来计算单个对象的体积,再乘以缓存对象的数量和预期增长(当然,这里边有一个热点数据的问题,这里就不细讨论了),大概得出需要使用的缓存空间;之后就可以按照这个指标去申请缓存空间或搭建缓存系统了。

      2.2 并发量

      这里说并发量,其实还不如说是QPS更贴切一些,因为我们的缓存不是直接面向用户的,而只面向应用的,所以肯定不会有那个高的并发访问(当然,多个系统共用一套缓存那就另当别论了);所以我们关心的是一个缓存系统平均每秒能够承受多少的访问量。

      我们之所以需要缓存系统,就是要它在关键时刻能抗住我们的数据访问量的;所以,缓存系统能够支撑的并发量是一个非常重要的指标,如果它的性能还不如关系型数据库,那我们就没有使用的必要了。

      对于淘宝的系统来说,我们不妨按照下边的方案来估算并发量:

      QPS = 日PV × 读写次数/PV ÷ (8 × 60 × 60)

      这里我们是按照一天8个小时来计算的,这个值基于一个互联网站点的访问规律得出的,当然,如果你不同意这个值,可以自己定义。

      在估算访问量的时候,我们不得不考虑一个峰值的问题,尤其是像淘宝、京东这样大型的电商网站,经常会因为一些大的促销活动而使PV、UV冲到平时的几倍甚至几十倍,这也正是缓存系统发挥作用的关键时刻;倍受瞩目的12306在站点优化过程中也大量的引入了缓存(内存文件系统)来提升性能。

      在计算出平均值之后,再乘以一个峰值系数,基本就可以得出你的缓存系统需要承受的最高QPS,一般情况下,这个系数定在10以内是合理的。

      2.3 响应时间

      响应时间当然也是必要的,如果一个缓存系统慢的跟蜗牛一样,甚至直接就超时了,那和我们使用MySQL也没啥区别了。

      一般来说,要求一个缓存系统在1ms或2ms之内返回数据是不过分的,当然前提是你的数据不会太大;如果想更快的话,那你就有点过分了,除非你是用的本地缓存;因为一般而言,在大型IDC内部,一个TCP回环(不携带业务数据)差不多就要消耗掉0.2ms至0.5ms。

      大部分的缓存系统,由于是基于内存,所以响应时间都很短,但是问题一般会出现在数据量和QPS变大之后,由于内存管理策略、数据查找方式、I/O模型、业务场景等方面的差异,响应时间可能会差异很多,所以对于QPS和响应时间这两项指标,还要靠上线前充分的性能测试来进一步确认,不能只单纯的依赖官方的测试结果。

      2.4 使用成本

      一般分布式缓存系统会包括服务端和客户端两部分,所以其使用成本上也要分为两个部分来讲;

      首先服务端,优秀的系统要是能够方便部署和方便运维的,不需要高端硬件、不需要复杂的环境配置、不能有过多的依赖条件,同时还要稳定、易维护;

      而对于客户端的使用成本来说,更关系到程序员的开发效率和代码维护成本,基本有三点:单一的依赖、简洁的配置和人性化的API。

      另外有一点要提的是,不管是服务端还是客户端,丰富的文档和技术支持也是必不可少的。

      2.5 扩展性

      缓存系统的扩展性是指在空间不足的性情况,能够通过增加机器等方式快速的在线扩容。这也是能够支撑业务系统快速发展的一个重要因素。

      一般来讲,分布式缓存的负载均衡策略有两种,一种是在客户端来做,另外一种就是在服务端来做。

      客户端负载均衡

      在客户端来做负载均衡的,诸如前面我们提到的Memcached、Redis等,一般都是通过特定Hash算法将key对应的value映射到固定的缓存服务器上去,这样的做法最大的好处就是简单,不管是自己实现一个映射功能还是使用第三方的扩展,都很容易;但由此而来的一个问题是我们无法做到failover。比如说某一台Memcached服务器挂掉了,但是客户端还会傻不啦叽的继续请求该服务器,从而导致大量的线程超时;当然,因此而造成的数据丢失是另外一回事了。要想解决,简单的可能只改改改代码或者配置文件就ok了,但是像Java这种就蛋疼了,有可能还需要重启所有应用以便让变更能够生效。

      如果线上缓存容量不够了,要增加一些服务器,也有同样的问题;而且由于hash算法的改变,还要迁移对应的数据到正确的服务器上去。

      服务端负载均衡

      如果在服务端来做负载均衡,那么我们前面提到的failover的问题就很好解决了;客户端能够访问的所有的缓存服务器的ip和端口都会事先从一个中心配置服务器上获取,同时客户端会和中心配置服务器保持一种有效的通信机制(长连接或者HeartBeat),能够使后端缓存服务器的ip和端口变更即时的通知到客户端,这样,一旦后端服务器发生故障时可以很快的通知到客户端改变hash策略,到新的服务器上去存取数据。

      但这样做会带来另外一个问题,就是中心配置服务器会成为一个单点。解决办法就将中心配置服务器由一台变为多台,采用双机stand by方式或者zookeeper等方式,这样可用性也会大大提高。

      2.6 容灾

      我们使用缓存系统的初衷就是当数据请求量很大,数据库无法承受的情况,能够通过缓存来抵挡住大部分的请求流量,所以一旦缓存服务器发生故障,而缓存系统又没有一个很好的容灾措施的话,所有或部分的请求将会直接压倒数据库上,这可能会直接导致DB崩溃。

      并不是所有的缓存系统都具有容灾特性的,所以我们在选择的时候,一定要根据自己的业务需求,对缓存数据的依赖程度来决定是否需要缓存系统的容灾特性。

      3 常见分布式缓存系统比较

      3.1 Memcached

      Memcached严格的说还不能算是一个分布式缓存系统,个人更倾向于将其看成一个单机的缓存系统,所以从这方面讲其容量上是有限制的;但由于Memcached的开源,其访问协议也都是公开的,所以目前有很多第三方的客户端或扩展,在一定程度上对Memcached的集群扩展做了支持,但是大部分都只是做了一个简单Hash或者一致性Hash。

      由于Memcached内部通过固定大小的chunk链的方式去管理内存数据,分配和回收效率很高,所以其读写性能也非常高;官方给出的数据,64KB对象的情况下,单机QPS可达到15w以上。

      Memcached集群的不同机器之间是相互独立的,没有数据方面的通信,所以也不具备failover的能力,在发生数据倾斜的时候也无法自动调整。

      Memcached的多语言支持非常好,目前可支持C/C++、Java、C#、PHP、Python、Perl、Ruby等常用语言,也有大量的文档和示例代码可供参考,而且其稳定性也经过了长期的检验,应该说比较适合于中小型系统和初学者使用的缓存系统。

      3.2 Redis

      Redis也是眼下比较流行的一个缓存系统,在国内外很多互联网公司都在使用(新浪微博就是个典型的例子),很多人把Redis看成是Memcached的替代品。

      下面就简单介绍下Redis的一些特性;

      Redis除了像Memcached那样支持普通的<k,v>类型的存储外,还支持List、Set、Map等集合类型的存储,这种特性有时候在业务开发中会比较方便;

      Redis源生支持持久化存储,但是根据很多人的使用情况和测试结果来看,Redis的持久化是个鸡肋,就连官方也不推荐过度依赖Redis持久化存储功能。就性能来讲,在全部命中缓存时,Redis的性能接近memcached,但是一旦使用了持久化之后,性能会迅速下降,甚至会相差一个数量级。

      Redis支持“集群”,这里的集群还是要加上引号的,因为目前Redis能够支持的只是Master-Slave模式;这种模式只在可用性方面有一定的提升,当主机宕机时,可以快速的切换到备机,和MySQL的主备模式差不多,但是还算不上是分布式系统;

      此外,Redis支持订阅模式,即一个缓存对象发生变化时,所有订阅的客户端都会收到通知,这个特性在分布式缓存系统中是很少见的。

      在扩展方面,Redis目前还没有成熟的方案,官方只给出了一个单机多实例部署的替代方案,并通过主备同步的模式进行扩容时的数据迁移,但是还是无法做到持续的线性扩容。

      3.3 淘宝Tair

      Tair是淘宝自主开发并开源的一款的缓存系统,而且也是一套真正意义上的分布式并且可以跨多机房部署,同时支持内存缓存和持久化存储的解决方案;我们数平这边也有自己的改进版本。

      Tair实现了缓存框架和缓存存储引擎的独立,在遵守接口规范的情况下,可以根据需求更换存储引擎,目前支持mdb(基于memcached)、rdb(基于Redis)、kdb(基于kyoto cabinet,持久存储,目前已不推荐使用)和rdb(基于gooogle的levelDB,持久化存储)几种引擎;

      由于基于mdb和rdb,所以Tair能够间距两者的特性,而且在并发量和响应时间上,也接近二者的裸系统。

      在扩展性和容灾方面,Tair自己做了增强;通过使用虚拟节点Hash(一致性Hash的变种实现)的方案,将key通过Hash函数映射到到某个虚拟节点(桶)上,然后通过中心服务器(configserver)来管理虚拟节点到物理节点的映射关系;这样,Tair不但实现了基于Hash的首次负载均衡,同时又可以通过调整虚拟节点和物理节点的映射关系来实现二次负载均衡,这样有效的解决了由于业务热点导致的访问不均衡问题以及线性扩容时数据迁移麻烦;此外,Tair的每台缓存服务器和中心服务器(configserver)也有主备设计,所以其可用性也大大提高。

    大型web系统数据缓存设计

      3.4 内存数据库

      这里的内存数据库只要是指关系型内存数据库。一般来说,内存数据库使用场景可大致分为两种情况:

      一是对数据计算实时性要求比较高,基于磁盘的数据库很难处理;同时又要依赖关系型数据库的一些特性,比如说排序、加合、复杂条件查询等等;这样的数据一般是临时的数据,生命周期比较短,计算完成或者是进程结束时即可丢弃;

      另一种是数据的访问量比较大,但是数据量却不大,这样即便丢失也可以很快的从持久化存储中把数据加载进内存;

      但不管是在哪种场景中,存在于内存数据库中的数据都必须是相对独立的或者是只服务于读请求的,这样不需要复杂的数据同步处理。

      4 缓存的设计与策略

      4.1 缓存对象设计

      4.1.1 缓存对象粒度

      对于本地磁盘或分布是缓存系统来说,其缓存的数据一般都不是结构化的,而是半结构话或是序列化的;这就导致了我们读取缓存时,很难直接拿到程序最终想要的结果;这就像快递的包裹,如果你不打开外层的包装,你就拿不出来里边的东西;

      如果包裹里的东西有很多,但是其中只有一个是你需要的,其他的还要再包好送给别人;这时候你打开包裹时就会很痛苦——为了拿到自己的东西,必须要拆开包裹,但是拆开后还要很麻烦的将剩下的再包会去;等包裹传递到下一个人的手里,又是如此!

      所以,这个时候粒度的控制就很重要了;到底是一件东西就一个包裹呢,还是好多东西都包一块呢?前者拆起来方便,后着节约包裹数量。映射到我们的系统上,我们的缓存对象中到底要放哪些数据?一种数据一个对象,简单,读取写入都快,但是种类一多,缓存的管理成本就会很高;多种数据放在一个对象里,方便,一块全出来了,想用哪个都可以,但是如果我只要一种数据,其他的就都浪费了,网络带宽和传输延迟的消耗也很可观。

      这个时候主要的考虑点就应该是业务场景了,不同的场景使用不同的缓存粒度,折衷权衡;不要不在乎这点性能损失,缓存一般都是访问频率非常高的数据,各个点的累积效应可能是非常巨大的!

      当然,有些缓存系统的设计也要求我们必须考虑缓存对象的粒度问题;比如说Memcached,其chunk设计要求业务要能很好的控制其缓存对象的大小;淘宝的Tair也是,对于尺寸超过1M的对象,处理效率将大为降低;

      像Redis这种提供同时提供了Map、List结构支持的系统来说,虽然增加了缓存结构的灵活性,但最多也只能算是半结构化缓存,还无法做到像本地内存那样的灵活性。

      粒度设计的过粗还会遇到并发问题。一个大对象里包含的多种数据,很多地方多要用,这时如果使用的是缓存修改模式而不是过期模式,那么很可能会因为并发更新而导致数据被覆盖;版本控制是一种解决方法,但是这样会使缓存更新失败的概率大大增加,而且有些缓存系统也不提供版本支持(比如说用的很广泛的Memcached)。

      4.1.2 缓存对象结构

      同缓存粒度一样,缓存的结构也是一样的道理。对于一个缓存对象来说,并不是其粒度越小,体积也越小;如果你的一个字符串就有1M大小,那也是很恐怖的;

      数据的结构决定着你读取的方式,举个很简单的例子,集合对象中,List和Map两种数据结构,由于其底层存储方式不同,所以使用的场景也不一样;前者更适合有序遍历,而后者适合随机存取;回想一下,你是不是曾经在程序中遇到过为了merge两个list中的数据,而不得不循环嵌套?

      所以,根据具体应用场景去为缓存对象设计一个更合适的存储结构,也是一个很值得注意的点。

      4.2 缓存更新策略

      缓存的更新策略主要有两种:被动失效和主动更新,下面分别进行介绍;

      4.2.1 被动失效

      一般来说,缓存数据主要是服务读请求的,并设置一个过期时间;或者当数据库状态改变时,通过一个简单的delete操作,使数据失效掉;当下次再去读取时,如果发现数据过期了或者不存在了,那么就重新去持久层读取,然后更新到缓存中;这即是所谓的被动失效策略。

      但是在被动失效策略中存在一个问题,就是从缓存失效或者丢失开始直到新的数据再次被更新到缓存中的这段时间,所有的读请求都将会直接落到数据库上;而对于一个大访问量的系统来说,这有可能会带来风险。所以我们换一种策略就是,当数据库更新时,主动去同步更新缓存,这样在缓存数据的整个生命期内,就不会有空窗期,前端请求也就没有机会去亲密接触数据库。

      4.2.2 主动更新

      前面我们提到主动更新主要是为了解决空窗期的问题,但是这同样会带来另一个问题,就是并发更新的情况;

      在集群环境下,多台应用服务器同时访问一份数据是很正常的,这样就会存在一台服务器读取并修改了缓存数据,但是还没来得及写入的情况下,另一台服务器也读取并修改旧的数据,这时候,后写入的将会覆盖前面的,从而导致数据丢失;这也是分布式系统开发中,必然会遇到的一个问题。解决的方式主要有三种:

      a、锁控制;这种方式一般在客户端实现(在服务端加锁是另外一种情况),其基本原理就是使用读写锁,即任何进程要调用写方法时,先要获取一个排他锁,阻塞住所有的其他访问,等自己完全修改完后才能释放;如果遇到其他进程也正在修改或读取数据,那么则需要等待;

      锁控制虽然是一种方案,但是很少有真的这样去做的,其缺点显而易见,其并发性只存在于读操作之间,只要有写操作存在,就只能串行。

      b、版本控制;这种方式也有两种实现,一种是单版本机制,即为每份数据保存一个版本号,当缓存数据写入时,需要传入这个版本号,然后服务端将传入的版本号和数据当前的版本号进行比对,如果大于当前版本,则成功写入,否则返回失败;这样解决方式比较简单;但是增加了高并发下客户端的写失败概率;

      还有一种方式就是多版本机制,即存储系统为每个数据保存多份,每份都有自己的版本号,互不冲突,然后通过一定的策略来定期合并,再或者就是交由客户端自己去选择读取哪个版本的数据。很多分布式缓存一般会使用单版本机制,而很多NoSQL则使用后者。

      4.3 数据对象序列化

      由于独立于应用系统,分布式缓存的本质就是将所有的业务数据对象序列化为字节数组,然后保存到自己的内存中。所使用的序列化方案也自然会成为影响系统性能的关键点之一。

      一般来说,我们对一个序列化框架的关注主要有以下几点:

      a 序列化速度;即对一个普通对象,将其从内存对象转换为字节数组需要多长时间;这个当然是越快越好;

      b对象压缩比;即序列化后生成对象的与原内存对象的体积比;

      c支持的数据类型范围;序列化框架都支持什么样的数据结构;对于大部分的序列化框架来说,都会支持普通的对象类型,但是对于复杂对象(比如说多继承关系、交叉引用、集合类等)可能不支持或支持的不够好;

      d易用性;一个好的序列化框架必须也是使用方便的,不需要用户做太多的依赖或者额外配置;

      对于一个序列化框架来说,以上几个特性很难都做到很出色,这是一个鱼和熊掌不可兼得的东西(具体原因后面会介绍),但是终归有自己的优势和特长,需要使用者根据实际场景仔细考量。

      我们接下来会讨论几种典型的序列化工具;

      首先我们先针对几组框架来做一个简单的对比测试,看看他们在对象压缩比和性能方面到底如何;

      我们先定义一个Java对象,该对象里主要包含了我们常用的int、long、float、double、String和Date类型的属性,每种类型的属性各有两个;

      测试时的样本数据随机生成,并且数据生成时间不计入测试时间;因为每种序列化框架的内部实现策略,所以即便是同一框架在处理不同类型数据时表现也会有差异;同时测试结果也会受到机器配置、运行环境等影响;限于篇幅,此处只是简单做了一个对比测试,感兴趣的同学可以针对自己项目中的实际数据,来做更详细、更有针对性的测试;

      首先我们先来看下几种框架压缩后的体积情况,如下表:

      单位:字节

    大型web系统数据缓存设计

      单位:纳秒

    大型web系统数据缓存设计

      综合来看,如果只处理数值类型,几种序列化框架的对象压缩比相差惊人,Protobuf和kryo生成的自己数组只有Hessian和Java的五分之一或六分之一,加上字符串的处理后(对于大尺寸文档,有很多压缩算法都可以做到高效的压缩比,但是针对对象属性中的这种小尺寸文本,可用的压缩算法并不多),差距缩小了大概一倍。而在处理时间上,几种框架也有者相应程度的差距,二者的增减性是基本一致的。

      Java源生序列化

      Java源生序列化是JDK自带的对象序列化方式,也是我们最常用的一种;其优点是简单、方便,不需要额外的依赖而且大部分三方系统或框架都支持;目前看来,Java源生序列化的兼容性也是最好的,可支持任何实现了Serializable接口的对象(包括多继承、循环引用、集合类等等)。但随之而来不可避免的就是,其序列化的速度和生成的对象体积和其他序列化框架相比,几乎都是最差的。

      我们不妨先来看一下序列化工具要处理那些事情:

      a、 首先,要记录序列化对象的描述信息,包括类名和路径,反序列化时要用;

      b、 要记录类中所有的属性的描述信息,包括属性名称、类型和属性值;

      c、 如果类有继承关系,则要对所有父类进行前述a和b步骤的处理;

      d、 如果属性中有复杂类型,这还要对这些对象进行a、b、c步骤的处理;

      e、 记录List、Set、Map等集合类的描述信息,同时要对key或value中的复杂对象进行a、b、c、d步骤的操作

      可见,一个对象的序列化所需要做的工作是递归的,相当繁琐,要记录大量的描述信息,而我们的Java源生序列化不但做了上边所有的事情,而且还做的规规矩矩,甚至还“自作多情”的帮你加上了一些JVM执行时要用到的信息。

      所以现在就是用脚都能够想明白,Java原生序列化帮你做了这么多事情,它能不慢么?而且还做得这么规矩(迂腐?),结果能不大么?

      下面就基本是各个工具针对Java弱点的改进了。

      Hessian

      Hessian的序列化实现和Java的原生序列化很相似,只是对于序列化反序列化本身并不需要的一些元数据进行了删减;所以Hessian可以像Java的源生序列化那样,可以支持任意类型的对象;但是在存储上,Hessian并没有做相应的优化,所以其生成的对象体积相较于Java的源生序列化并没有下降太多;

      比如,Hessian对于数值类型仍然使用了定长存储,而在通常情况下,经常使用的数据都是比较小的,大部分的存储空间是被浪费掉的;

      为了标志属性区段的结束,Hessian使用了长度字段来表示,这在一定程度上会增大结果数据的体积;

      由于Hessian相较于Java源生序列化并没有太大的优势,所以一般情况下,如果系统中没有使用Hessian的rpc框架,则很少单独使用Hessian的序列化机制。

      Google Protobuf

      GPB最大的特点就是自己定义了一套自己数据类型,并且规定只允许用我的这套;所以在使用GPB的时候,我们不得不为它单独定义一个描述文件,或者叫schema文件,用来完成Java对象中的基本数据类型和GPB自己定义的类型之间的一个映射;

      不过也正是GPB对类型的自定义,也让他可以更好的针对这些类型做出存储和解析上的优化,从而避免了Java源生序列化中的诸多弱点。

      对于对象属性,GPB并没有直接存储属性名称,而是根据schema文件中的映射关系,只保存该属性的顺序id;而对于,GPB针对常用的几种数据类型采用了不同程度的压缩,同时属性区段之间采用特定标记进行分隔,这样可以大大减少存储所占用的空间。

      对于数值类型,常见的压缩方式有变长byte、分组byte、差值存储等,一般都是根据属性的使用特点来做定制化的压缩策略。

      GPB的另一个优点就是跨语言,支持Java、C、PHP、Python等目前比较大众的语言;其他类似的还有Facebook的Thrift,也需要描述文件的支持,同时也包含了一个rpc框架和更丰富的语言支持;

      Kryo

      前面我们提到,诸如Hessian和GPB这些三方的序列化框架或多或少的都对Java原生序列化机制做出了一些改进;而对于Kryo来说,改进无疑是更彻底一些;在很多评测中,Kryo的数据都是遥遥领先的;

      Kryo的处理和Google Protobuf类似。但有一点需要说明的是,Kryo在做序列化时,也没有记录属性的名称,而是给每个属性分配了一个id,但是他却并没有GPB那样通过一个schema文件去做id和属性的一个映射描述,所以一旦我们修改了对象的属性信息,比如说新增了一个字段,那么Kryo进行反序列化时就可能发生属性值错乱甚至是反序列化失败的情况;而且由于Kryo没有序列化属性名称的描述信息,所以序列化/反序列化之前,需要先将要处理的类在Kryo中进行注册,这一操作在首次序列化时也会消耗一定的性能。

      另外需要提一下的就是目前kryo目前还只支持Java语言。

      如何选择?

      就Java原生序列化功能而言,虽然它性能和体积表现都非常差,但是从使用上来说却是非常广泛,只要是使用Java的框架,那就可以用Java原生序列化;谁让人家是“亲儿子”呢,即便是看在人家“爹”的份儿上,也得给人家几分面子!

      尤其是在我们需要序列化的对象类型有限,同时又对速度和体积有很高的要求的时候,我们不妨试一下自己来处理对象的序列化;因为这样我们可以根据要序列化对象的实际内容来决定具体如何去处理,甚至可以使用一些取巧的方法,即使这些方法对其他的对象类型并不适用;

      有一点我们可以相信,就是我们总能在特定的场景下设计出一个极致的方案!


    http://tech.it168.com/a2015/1208/1790/000001790321.shtml

    展开全文
  • 1.最近mac系统文件多黄色部分占了部分。 2.如何快速解决黄色部分占比过高? 点击前往,然后按住alt,会出现一个资源库找到如下文件夹。 3.在资源库中找到Containers这个文件夹。 确定您平时用的软件哪些多,你就...
        

    1.最近mac系统文件太多黄色部分占了大部分。

    2.如何快速解决黄色部分占比过高?
    点击前往,然后按住alt,会出现一个资源库找到如下文件夹。
    3.在资源库中找到Containers这个文件夹。
    确定您平时用的软件哪些多,你就删哪些吧。全是一堆数据很杂的。
    比如常用qq,你就把com.tencent.qq删除,能删除个7到8个g,其余的软件您要是用的多,不想备份的话,也可以随便删。
    这样就能清理完毕。

    OmniDiskSweeper

    展开全文
  • 数据分析与数据管理系统实践 一、数据介绍 公司员工信息 ,Excel文件 提供 44 名员工 姓名、所在部门工作职务车的编号 公司员工的信用卡刷记录(两周) ,Excel 文件 约 1400 行信用卡刷记录,内容包括:员工...

    数据分析与数据管理系统实践

    一、数据介绍

    公司员工信息 ,Excel文件

    提供 44 名员工 姓名、所在部门工作职务车的编号

    公司员工的信用卡刷记录(两周) ,Excel 文件

    约 1400 行信用卡刷记录,内容包括:员工姓名、地点称金额时间

    二、大作业要求

    1、根据自己所学数据库操作和管理知识,创建一个数据库,把两个Excel表导入这个数据库,并对应建立两个表;对两个表创建主键、外键、索引,还可以自己增加一些列,或者做一些视图;

    2、综合运用自己所学的查询语句和SQL开发技巧对数据进行统计分析,并要求回答如下问题;

    问题一:员工的消费有一些什么有趣的模式和规律,请写出你分析的SQL语句,并截取分析结果,说明你是如何找到的这些模式和规律的;(不少于5个模式)

    问题二:员工的消费有什么异常现象,你是如何找到这个异常的,请写出你得到分析的SQL语句,并截取分析结果。(不少于3个异常)

    3、学习一门开发工具,开发一个小型数据库管理系统

    系统基本功能1:增加、删除和修改这两个表的记录

    系统基本功能2:提供输入框接受用户手动输入SQL查询语句,能输出用户任意输入的SQL查询语句的查询结果。

    系统基本功能3:能够按人、按消费地点、按天这三种组合,设计并输出几个统计报表。

     

    三、实验过程及结果

    1、创建“大数据作业”数据库后,右键点击该数据库,选择【任务】—>【导入数据】,如右图所示:


    2、选择导入的数据源,下一步,选择导入的数据库目标,如下图所示:

    3、在指定表复制或查询中应该可以选择【编写查询已指定要传输的数据】对数据进行清洗,尝试着写SQL语句过滤到脏数据,但没有成功,所以就选择直接先全将数据导入到数据库,再对数据进行过滤。

    4、通过对数据的查询,我们可以发现creditcard表中存在一些类似“Katerina抯 Caf?28”的奇字符,下面在数据库里对表中数据进行清洗。

    5、新建查询对数据清洗,并将新的数据建立一张新表。

    将employee表中FirstName和LastName合并,创建newemployee表

    select FirstName+' '+LastName as name,CurrentEmploymentType,CurrentEmploymentTitle
    
    into newemployee
    
    from employee

    将creditcard表中FirstName和LastName合并,创建newcreditcard表

    select FirstName+' '+LastName as name,timestamp,location,price
    
    into newcreditcard
    
    from creditcard

    通过对两张表的name查询,可以发现newemployee表共44名员工,newcreditcard表去掉为NULL共55人

    select distinct name
    
    from newemployee
    
    
    
    select distinct name
    
    from newcreditcard

    在这里我们对存在newemployee表中的44名员工进行对他们的消费记录的查询,可以发现creditcard表中错误不会影响,当然也可以尝试清洗一下数据

    select *
    
    into newcreditcard1
    
    from newcreditcard
    
    where name in (
    
    select name
    
    from newemployee
    
    )

    清洗数据:

    select *
    
    into newcreditcard
    
    from credtcard
    
    where location not like '%[0-9]%'and FirstName is not NULL and LastName is not NULL


    6、设置表中数据的数据类型、主键,newemployee表中FirstName、LastName没有重复项,可以设置为主键,而newcreditcard1表中有重复项,如果要设置主键,就必须FirstName、LastName、timestamp、location都设置为主键。

    7、分析数据:

    (1)模式和规律

    ① 查询每个人两周内的消费总金额和职业,可以发现卡车司机职业的消费金额比其他人都高,Valeria Morlun消费最多。


    ② 查询所有消费地点的消费人次,可以发现Hippokampos、Guy's Gyros、Brew've Been Served普遍比其他地方消费次数高,比较受欢迎。


    ③ 查询每个人到某个地点的消费次数,可以发现大部分人两周内基本每天都去某个地方消费一次。

    ④ 查询每天所有人的消费次数总和,可以发现6号至10号五天和13号至17号五天,消费次数比11、12号和18、19号要多,可以猜想工作日出门次数比周末次数多,消费次数多。

    ⑤ 查询每天某一时间段内的消费次数,将一天分24小时为【00:00:00-03:00:00】、【03:00:00-06:00:00】、【06:00:00-09:00:00】、【09:00:00-12:00:00】、【12:00:00-15:00:00】、【15:00:00-18:00:00】、【18:00:00-21:00:00】、【21:00:00-24:00:00】八个时间段,发现【00:00:00-03:00:00】、【03:00:00-06:00:00】、【15:00:00-18:00:00】这几个时间段消费次数较少,大多数消费集中在其他时间段:早餐、午餐、下午茶、晚餐。

    【06:00:00-09:00:00】


    【09:00:00-12:00:00】


    【12:00:00-15:00:00】


    【15:00:00-18:00:00】

    【18:00:00-21:00:00】


    【21:00:00-24:00:00】


    【00:00:00-03:00:00】


    【03:00:00-06:00:00】

    (2)异常现象

    ① Adan Morlun和Claudio Nant两人消费次数都比较少且平均消费金额比较大,最大单笔消费也比较多。

    select FirstName,LastName,COUNT(*)as '消费次数',SUM(price)as '总金额',AVG(price)as '平均消费金额',MAX(price)as '单笔最大消费'
    
    from newcredtcard
    
    group by FirstName,LastName 
    
    order by AVG(price)desc

    ② 13号的凌晨【00:00:00-03:00:00】和12、13号【03:00:00-06:00:00】有消费记录

    ③ Maximum Iron and Steel、Abila Scrapyard这几个地点,消费次数少,且金额大,平均金额也很大。

    select location,COUNT(*)as '消费次数',SUM(price)as '总金额',AVG(price)as '平均消费金额',MAX(price)as '单笔最大消费'
    
    from newcreditcard
    
    group by location
    
    order by AVG(price)desc

    8、数据库开发

    开发工具:Delphi 2010

    开发环境:Windows XP(在虚拟机上完成的,SQL Server Management Studio也在XP里,因为我的主机Win10安装不成功)

    开始选择Delphi 7 ,但感觉界面不太友好,就又重新选了Delphi 2010安装,安装网上有教程,破解也有,但没有破解出来,且只有14天的试用期。DevExpress VCL 13.1.4是后面网上找教程安装的插件,主要是一些控件的使用会用到,根据网上教程以及《Delphi程序开发范例宝典》进行数据库开发,具体实验截图见下:

    主界面:

    主体框架结构:

    Ucreadtcard.pas:对creditcard表(这里命名错了)的增删改操作的主程序;

    UDMmain.pas:数据库连接模块,后面会看到;

    Uemployee.pas:对employee表的增删改操作的主程序;

    Ugroup.pas:对creditcard表分组查询操作(按人、地点、天)的主程序;

    Umain.pas:主窗口程序;

    USQL.pas:SQL查询的主程序


    主窗口:设置了SQL查询、employee表、creditcard表、统计,四个按钮,通过dxBarManager进行管理,点击触发通过ActionList管理,dxSkinController界面皮肤管理控件。


    按钮触发事件代码如下:

    Employee表的窗口界面,一张表控件和数据库导航控件,导航控件可以对数据库进行增删改操作,creditcard表一样。


    ADOConnection连接数据库,ADOQuery查询数据库,DataSource查询后的数据源

    SQL查询界面,Memo接收SQL语句,查询按钮触发事件进行查询,表输出结果。


    设计代码如下:

    分组查询,设置查询条件,按人、地点、时间进行查询。


    给ComboBox设置选项,即查询列下的所有数据对象,代码如下图:


    按钮触发,进行查询,代码如下:

    实验测试结果如下:

    启动主界面;

    点击SQL查询按钮,输入SQL语句,点击查询。


    点击employee表,进行对该表的增删改,增是“+”,删是“-”,改直接在表中改,然后点击“√”

    增加数据的效果,SQL Sever数据库中增加了这么一行,如下图:


    删除数据的效果,选中某行数据,点击“-”按钮,删除数据。

    改,直接在表中改就行,然后点击“√”按钮。

    点击统计按钮,进行分组查询,从下拉框中选出查询的对象,点击查询就可以进行条件查询。

     

    四、总结

    通过本次数据库大作业实验,进一步巩固了我对数据库的基本操作,同时锻炼了对数据的分析能力,以及初步认识和学习数据库开发,掌握了一些数据库开发的基本操作。对于语言,无论是SQL语言、数据库开发语言,还是C、Java,都有其固定的结构,和类似的语法,函数调用、参数传递,可能一看就知道它在做什么,还有网上视频教程资源很多,对于语言、开发的学习有很大帮助,希望在今后学习中能提升更多。

    展开全文
  • 接口返回的数据太大很耗非带宽

    千次阅读 2019-09-22 22:09:10
    占用带宽无非就是接口返回的数据量过导致,所以我就排查了下项目中返回数据量较的几个接口,当中的一个也是访问很频繁的接口 获取即时列表接口最大返回数据量有时会超过2M!!! 我靠,更可怕的是这个接口还是.....
  • 由于数据库中表数据太大,数据库设计不太合理,导致表中存放100多万条记录就查询非常慢,而且查询频率非常高,涉及的报表统计也比较多,插入修改删除频率也较高,对程序响应速度造成了很大影响。 &nbsp;&...
  • 公司查询报表出现问题,只能通过月份进行筛选,得到的数据过于庞大,导致...2,解决数据库插入问题(不能根本解决问题,数据,获取数据依然会缓慢) Get azure usage: 首先,查询查询接口相关方法: 1,htt...
  • 问题:页面展示调用查询方法查询全部数据的时候一直显示loading。。。,打开调试器显示Failed to load resource: net::ERR_SPDY_PROTOCOL_ERROR,而少部分查询则正常显示。 因为数据中有图片转成的二进制数组,数据...
  • 大数据量报表系统的改进方案

    万次阅读 2016-12-31 21:45:13
    如果是行家,提起报表,你是否想起了JasperReports( iReport )、Birt、JFreeReport、水晶报表等?...但是我讲的是一种大数据量的报表,可能不是一张word或者几千条的excel能够导出的,比如说订单报表、销
  • 1.合理使用索引索引是数据库中重要的数据结构,它的根本目的就是为了提高查询效率。现在大多数的数据库产品都采用IBM最先提出的ISAM索引结构。索引的使用要恰到好处,其使用原则如下:●在经常进行连接,但是没有...
  • 2020王道操作系统,2020王道数据结构,2020王道计算机网络,2020王道计算机组成原理pdf合集 资料链接: https://shimo.im/docs/QCgdKCTpypjHdhXg/ 一年又一年,参加计算机考研的大军越来越多,408到底有多难,初试...
  • python处理训练集过程中经常会遇到的Memory Error问题 这里看了几位博主的解决方案进行了整理,感谢分享! http://chenqx.github.io/2014/10/29/Python-fastest-way-to-read-a-large-file/ ......
  • 分布式系统数据分片

    千次阅读 2018-05-19 09:27:18
    正文 在前文中,提出了分布式系统(尤其是分布式存储系统)需要解决的两个最主要的问题,即数据分片和数据冗余,下面这个图片(来源)形象生动的解释了其概念和区别: 其中数据即A、B属于数据分片,原始数据被拆分...
  • 本文探讨数据应用层中的运营数据系统,因为运营数据几乎是所有互联网创业公司开始做数据的起点,也是早期数据服务的主要对象。本文将着重回顾下我们做了哪些工作、遇到过哪些问题、如何解决并实现了相应的功能。
  • 上海立邦TU报销系统,是上海立邦集团针对内部的报销的业务,编写的一套系统,此系统主要特点是和Web、SAP和Notes等系统实现无缝对接,从而完成整体业务的流转,目前立邦已经存在SAP报销系统、Notes系统,情况如下: ...
  • 各种信息管理系统本质上是没有太大区别的,对于数据的操作都是差不多的。 2.功能及其相关函数 2.1 菜单界面的构建 建立两个界面函数,用来搭建主页,这里用到两个头文件 #include<conio.h> 定义了通过控制台的...
  • 这个项目是我们小组的一个结课作业,但是部分都是我亲自完成的,这里仅分享我制作的那部分(主要是因为同学后来加的那部分语音识别鸡肋,点了检测按钮还得再说一声开始检测才能打开摄像头,我觉得毫无意义)。...
  • 评价系统海量数据存储设计

    万次阅读 2016-08-16 09:05:57
    京东的商品评论目前已达到数十亿条,每天提供的服务调用也有数十亿次,而这些数据每年还在成倍增长,而数据存储是其中最重要的部分之一,接下来就介绍下京东评论系统数据存储是如何设计的。   整体数据存储...
  • 分布式系统学习——数据分片

    千次阅读 2018-12-15 17:16:29
    开始学习之前,先简单接受下分布式系统是什么。 分布式系统是什么 这里我先以百度百科上搜索分布式系统为依据,结合自己的理解,做个简单的概括。 分布式系统(distributedsystem)是建立在网络之上的软件系统。...
  • 前面放完建设四个现代化大数据平台乌托邦理想的大卫星,接下来的文章得谈谈具体...本文重点谈理论,会先从的场景划分的角度对市面上的各种调度系统进行分类讨论,然后再针对具体的作业调度系统,探讨一下各自的优缺点
  • 基础系统数据采集工作总结

    千次阅读 热门讨论 2013-12-18 21:24:51
     11月22日:接到基础系统数据采集的通知,心想上次的数据采集没有出现太大的出入,就答应了下来。与相关负责人讨论了一番,结论是:按照上次的方式培训十期人员,描述各表关系,理清思路,每个二级学院派去一个十期...
  • 这个问题出现的场景并不是很多,当你向服务端异步(ajax)post数据非常的情况下(比如做权限管理的时候给某个角色分配权限那么就可能会出现,我所遇到的就是该角色大概200个模块每个模块平均2个功能----那么发送到...
  • 新旧系统更替产生的数据迁移问题

    千次阅读 2014-12-29 15:44:56
    新旧系统更替产生的数据迁移问题 作者:西安项目组夏凯撰文时间:2004.11.08 在信息化建设过程中,随着技术的发展,原有的信息系统不断被功能更强大的新系统所取代。从两层结构到三层结构,从Client/Server到...
  • Windows系统SNMP数据监测与OID

    万次阅读 热门讨论 2016-08-19 20:17:49
    Window通过SNMP获取系统数据的说明 初步接触SNMP(Simple Network Management Protocol)简单网络管理协议之后,对windows系统的监测有了兴趣,通过一段时间的查找资料与实际测试,将系统的一些简单数据通过SNMP协议...
  • 大屏数据可视化设计指南

    万次阅读 多人点赞 2019-01-03 14:25:31
    把相对复杂、抽象的数据通过可视的方式以人们更易理解的形式展示出来的一系列手段叫做数据可视化,数据可视化是为了更形象地表达数据内在的信息和规律,促进数据信息的传播和应用。 在当前新技术支持下,数据可视化...
  • 数据库建模能力在企业业务系统开发中是重要技能之一,相比互联网公司,编程技术虽然不会有太大难度,但是,业务建模过程中建立好数据关系表,代码实现中写好每一个逻辑细节,对思维能力的方面还是有一定要求的。
  • 但是两个系统需要并存上线一段时间,两边都有可能有查询和修改数据的操作,新老系统的底层数据库结构设计不同,需要两边互相同步业务数据数据不允许丢失,且延迟不能长,几秒内可以接受。 板上各位前辈、牛...
  • 应用系统数据对接几种方案

    万次阅读 2018-03-12 09:21:59
    应用系统之间数据传输的几种方式第一种方案:socket方式 Socket方式是最简单的交互方式。是典型才C/S交互模式。一台客户机,一台服务器。服务器提供服务,通过IP地址和端口进行服务访问。而客户机通过连接服务器...
  • 数据密集型系统架构设计

    万次阅读 2016-05-19 20:07:30
    同时,我们看到内存除了访问速度越来越快,在存储的数据量和成本上并没有太大的变化。因此,未来越来越多的系统的主要瓶颈会从计算、IO转移到数据量上,内存密集型系统会变得越来越重要,相信其架构在未来几年也会有...
  • 我们的大数据量查询是数据库分页的,但是导出和打印功能是基于全部数据的.系统投入使用后,对于导出和打印功能的使用远远要高于我们的预期.而我们的系统的硬件设备是有限的 不能再升级了.抓取内存对象的时候,常常...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,218,763
精华内容 487,505
关键字:

其他系统数据太大