`

Arch-03-14-缓存策略

 
阅读更多

Arch-03-14-缓存策略

 

robin(有人谓肉饼,太有才了)的一文很强悍,摘在这儿做个灯引。

http://robbin.iteye.com/blog/770553

 

 

 写道
操作系统磁盘缓存
数据库缓存
--Query Cache
--Data Buffer
应用程序缓存
--对象缓存
--查询缓存
页面内部缓存
--动态页面静态化
--Servlet缓存
Web服务器缓存
--squid/nginx
--CDN
客户端浏览器缓存
--AJAX缓存
--基于HTTP协议的资源缓存
如果是对象Cache,自然是ORM透明化出来; 
如果是查询Cache,自然是DAO层处理; 
如果是Action Cache,自然是Web 层Action处理; 
如果是Page Cache,自然是Servlet Filter处理;

用 ibatis + memcached 的策略明显有缺陷,粒度太大,考虑用更小粒度高效的方案吧。

 

听起来 hibernate 的缓存不错,原理很好,之前的项目一直是类似机制,只不过用的是自己实现的 simpleJdbc. 现在需要在 ibatis 的基础上实现细粒度缓存,好象没那么简单。

 

=================================================

1.  Voldemort (伏地魔)

  • 一致性
  • 可插拔
  • 独立
  • 一个强大的Java客户端,支持可插拔的序列化
  • 可整合
2. 尽管 ibatis 无好的方法直接配对象缓存,但项目已经使用 ibatis 很久了(历史遗留问题),还得改造成 ibatis + 对象缓存 +查询缓存,不过不指望 ibatis 本身能做什么,权把它当作 SQL解析器,想办法把返回的对象作缓存吧。其中有个关键点,就是对象中包含下级对象的处理。
    (1)ibatis 对下级对象的处理是直接对象实例化后返回,如果是一对多(父子)关系的情形,则返回的父对象中已经包含了全部的子对象,使用起来是比较方便,可缓存的粒度就肥大了许多,几乎无法控制。比如基于一树型组织机构的查询,公司级、部门级、个人级三级过滤分三个查询,查询出来的记录集可以想象是个什么样子了,大部份是重复的,把这些对象整包放入缓存,还真有些不伦不类。
    (2)理想的方法不应该将子对象实例化后放入父对象,而应该存放 ID 的 list。有段代码以 JDBC 为例。

 public MessageBean getByID(long id)
    throws MessageNotFoundException, DAOException
  {
        MessageBean bean = null;

        Connection con = getConnection();
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try
        {
        	// load message row
          pstmt = con.prepareStatement("SELECT pMessageID, ownerID, senderID, recipientID, subject, body, readStatus, folderID, pMessageDate, status, creationDate, sentDate FROM message WHERE pMessageID = ?");
          pstmt.setLong(1, id);

          rs = pstmt.executeQuery();
          if (!rs.next()) {
            throw new MessageNotFoundException("Message " + id + " could not be loaded from the database.");
          }

          bean = read(rs, new MessageBean());

          rs.close();
          pstmt.close();

        	// load message properties rows
          Map p = new HashMap();
          pstmt = con.prepareStatement("SELECT name, propValue FROM MessageProp WHERE pMessageID=?");
          pstmt.setLong(1, id);
          rs = pstmt.executeQuery();
          while (rs.next())
          {
            p.put(rs.getString(1), rs.getString(2));
          }
          bean.setProperties(p);
          rs.close();
          pstmt.close();

        	// load message attachment IDs
          LongList attachmentList = new LongList();
          try
          {
            pstmt = con.prepareStatement("SELECT attachmentID FROM attachment WHERE objectType=5 AND objectID=?");
            pstmt.setLong(1, bean.getID());
            rs = pstmt.executeQuery();
            while (rs.next()) {
              attachmentList.add(rs.getLong(1));
            }
            bean.setAttachments(attachmentList);
          }
          catch (SQLException sqle) {
            Log.error(sqle);
          }
          finally {
            ConnectionManager.close(rs, pstmt);
          }
        }
        catch (SQLException sqle) {
          throw new MessageNotFoundException("Message with id " + id + " could not be loaded from the database.");
        }
        catch (NumberFormatException nfe)
        {
          throw new MessageNotFoundException("Message with id " + id + " could not be loaded from the database.");
        }
        finally
        {
          ConnectionManager.close(rs, pstmt);
          releaseConnection(con);
        }

        return bean; 
  }
  
3. 历尽黑暗,总算勉强制伏了伏地魔,同时还有应用的集群。

(3.1) voldemort 配置文件

#!/bin/bash/voldemort-service.sh

#
#   Copyright 2008-2009 LinkedIn, Inc
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
#

if [ $# -gt 1 ];
then
	echo 'USAGE: bin/voldemort-server.sh [voldemort_home]'
	exit 1
fi

base_dir=$(dirname $0)/..

for file in $base_dir/dist/*.jar;
do
  CLASSPATH=$CLASSPATH:$file
done

for file in $base_dir/lib/*.jar;
do
  CLASSPATH=$CLASSPATH:$file
done

for file in $base_dir/contrib/*/lib/*.jar;
do
  CLASSPATH=$CLASSPATH:$file
done

CLASSPATH=$CLASSPATH:$base_dir/dist/resources

if [ -z "$VOLD_OPTS" ]; then
  VOLD_OPTS="\
-Xmx2G -server \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=6650 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false"
fi

java -Dlog4j.configuration=log4j.properties $VOLD_OPTS -cp $CLASSPATH voldemort.server.VoldemortServer $@
 
不要持久化,只要内存缓存的配置

<!--cluster.xml-->
<cluster>
<name>pluscluster</name>
<server>
    <id>0</id>
    <host>127.0.0.1</host>
    <http-port>8071</http-port>
    <socket-port>6666</socket-port>
    <admin-port>6667</admin-port>
    <partitions>0,1,2,3,4,5,6,7
    </partitions>
</server>
</cluster>

server.properties
 
# The ID of *this* particular cluster node
node.id=0

max.threads=100

############### DB options ######################

http.enable=false
socket.enable=true
jmx.enable=true
storage.configs=voldemort.store.bdb.BdbStorageConfiguration,voldemort.store.memory.InMemoryStorageConfiguration,voldemort.store.memory.CacheStorageConfiguration
slop.store.engine=memory

# NIO connector settings.
enable.nio.connector=true
enable.nio.admin.connector=false

# don't throttle admin client - set to a really high value
stream.read.byte.per.sec=1000000000000
stream.write.byte.per.sec=1000000000000

# default buffer size is 10MB. We'll turn it down to 512KB
admin.streams.buffer.size=524288

# use only 8 selectors (for nio)
nio.connector.selectors=8
nio.admin.connector.selectors=8

 

4. 应用架构基于共享 Voldemort 缓存,利用 JGroup 传送消息的应用集群,讲起来有一匹布那么长,暂且略过,隔几天画个图上来。


 

5. 启动 JMX 监控

 

开启一个Jconsole 本地连接
 


 

 

6. 缓存性能优化之道

 

(1)客户端资源缓存

 

 

HTTPD server - “cache.conf.rpmnew”

 

(2)服务端页缓存

 

 

HTTP header in the response to Cache-Control max-age=3600.
 

 

(3)配置外部 CDN 缓存服务器

 

 

. 安装 CDN 缓存服务器
. 基于 URL
. 服务器端生成页面时,重写静态资源地址指向 CDN URL
. 当完成页面请求后,客户端使用 CDN URL 返回资源
. 如果 CDN 命中,直接返回客户端,否则,从应用服务器返回并存入 CDN,备用。

 

 

 

 

(4)调整虚拟机参数

 

 

JVM_HEAP_MAX=4096
JVM_HEAP_MIN=4096
 

 

7. 动手搭建山寨 CDN

 

 

参考原文 http://blog.csdn.net/jackem/article/details/3206440

目前对于 CDN 网络搭建技术有很多成熟的商业方案,对于资金受限的网站可能无法自己搭建或购买。这里提供了一套简单的实现CDN网络的技术架构,所使用的软件全部是开源高效且免费的。根据CDN网络技术原理,必须有一个动态DNS服务器,开源的可以使用bind,免费开源。不修改代码,bind 基本上可以实现简单的动态DNS解析功能。需要更强的自定义功能,可以自己修改代码实现。

(1)假设web站点部署在上海电信。

(2)在上海电信部署Bind,提供动态解析服务,在上海电信部署主Web站点;

(3)在全国各地找几个比较重要的机房部署 lighttpd 服务器提供静态资源下载,如北京网通,广州电信两个机房各放置2台服务器,安装上 lighttpd+mod_cache+mod_proxy 等;

(4)配置子下载服务器的 lighttpd 的 modCache 功能,并设置 proxy.server 为主站点上海机房IP。

(5)当北京网通用户访问主站的静态文件时,通过动态DNS解析得到北京网通机房服务器的IP地址,浏览器就从北京网通服务器上下载文件了,提高了响应速度,同时降低了主站的压力。

这样一个简单的技术架构已经完成。对于 lighttpd+modCache 的详细配置参考http://www.linux.com.cn/modcache/。

 

 

 


    <bean id="usersCache" parent="cacheBean" depends-on="cacheFactoryManager">
        <constructor-arg value="Users" />
        <property name="type" ref="local"/>
        <!-- in milliseconds, 24 hours, checked every hour -->
        <property name="expirationTime" value="86400000"/>
        <property name="expirationPeriod" value="3600000"/>
        <property name="transactional" value="false"/>
        <property name="keyRetrieval" value="false"/>
        <property name="type" value="false"/>
        <property name="timeoutTime" value="60"/>
        <property name="timeUnit" value="false"/>
        <property name="additionalProperties" value="Map<String, String>"/>
        <property name="valueSerializer" value="false"/>
        <property name="disableEviction" value="false"/>
        <property name="prefixAware" value="false"/>
        <property name="maxCacheSize" value="10g"/>
        <sizeLimit
    </bean>

  • 大小: 65.5 KB
  • 大小: 109.7 KB
  • 大小: 24.9 KB
  • 大小: 28 KB
分享到:
评论

相关推荐

    Arch-03-15- Nginx+tomcat 配置负载均衡动静分离

    标题“Arch-03-15- Nginx+tomcat 配置负载均衡动静分离”涉及的是在Web服务器架构中使用Nginx与Tomcat的集成,通过配置实现负载均衡和动静态资源分离。这样的架构可以提高系统的可用性和响应速度,减轻后端应用...

    USTC-ARCH-Labwork:体系结构部分lab

    理解缓存的工作原理,如替换策略、写策略,以及缓存的命中率对性能的影响。 3. **总线与I/O接口**:介绍总线的作用,如何传输数据和控制信号,以及I/O设备的接口设计,如DMA(直接存储器访问)和中断处理。 二、...

    hadoop-arch-book:O'Reilly Hadoop 应用程序架构书的代码库

    这可能涉及到数据分片策略、reduce任务数量的调整、缓存使用等。 8. **YARN资源调度**:YARN(Yet Another Resource Negotiator)是Hadoop 2.x引入的资源管理系统,用于统一管理和调度整个集群的资源。书中可能讲解...

    北大计算机系高级计算机系统结构课件chx14-arch02-cache1

    缓存的大小、替换策略(如LRU、LFU等)、一致性协议(如MESI、MOESI等)以及预取技术等都是关键因素,它们直接影响到缓存的命中率和系统性能。例如,Alpha 21164、StrongArm SA110和Pentium Pro等处理器通过增加缓存...

    北大计算机系高级计算机系统结构课件chx14-arch08-mm1

    为解决这一问题,计算机架构师引入了高速缓存(Cache)机制,即在CPU与DRAM之间设置了一个小而快的Cache,从而减少了CPU在等待数据时的空闲时间。这种内存层次结构的设计,有效地缓解了CPU与主存之间速度不匹配的...

    ARCH4系统开发指南

    2.8.2 实现Sequence主键生成策略 21 2.9 如何清除Hibernate Session中的对象 22 2.10 使用日期控件 22 2.11 如何引入外部文件 23 2.11.1 主页面采用include方式,引入各个子页面jsp文件 23 2.11.2 主页面用${ctx}...

    nginx1.23.2-麒麟-aarch64

    - 配置文件通常位于`/etc/nginx/nginx.conf`,用户可以通过修改配置来定制服务器行为,如设置虚拟主机、调整缓存策略等。 - 命令行工具如`nginx -t`用于测试配置文件的正确性,`nginx -s reload`则用于在不中断...

    redis6.2.7-ky10.aarch64

    Redis,全称Remote Dictionary Server,是一款高性能的键值存储系统,常被用作数据库、缓存和消息中间件。在本场景中,我们讨论的是Redis的6.2.7版本,针对aarch64架构(即64位ARM处理器)的ky10定制版。 Redis的...

    dist-app-arch:Jave Web应用程序开发证书的#3分布式应用程序体系结构的分配项目

    在本项目中,“dist-app-arch: Java Web应用程序开发证书的#3分布式应用程序体系结构的分配项目”,我们探讨的是如何构建可扩展、高效且可靠的Java Web应用程序,这通常涉及到分布式系统的设计与实现。分布式应用...

    comp_arch

    在这个"comp_arch"项目中,我们主要关注两个核心组件:缓存模拟器和分支预测器,这些都是现代处理器性能优化的关键技术。 缓存模拟器是一个工具,用于模拟和分析处理器中的缓存系统。缓存是计算机存储层次结构的一...

    .arch实验报告__封面.doc

    - 存储层次结构:探索内存层次,包括高速缓存、主存和硬盘的访问速度和特性。 - 输入/输出(I/O)系统:理解设备驱动程序的角色,进行I/O操作模拟。 - 性能分析:使用工具(如gprof, perf等)分析程序执行的性能...

    nginx--aarch64.rar

    - 负载均衡策略包括轮询、权重轮询、最少连接数、IP哈希等,可根据实际需求选择合适的方式。 7. **缓存功能**: - Nginx可以作为缓存服务器,预先加载常用资源,减少对后端服务器的压力,提高响应速度。 - 使用`...

    The MIPS Cache Architecture

    - **写分配策略**:当缓存数据被修改时,是否立即更新缓存中的数据行。 #### MIPS缓存架构在Linux下的应用 在Linux操作系统中,针对MIPS内核的缓存管理尤为重要。Linux内核通过一系列的缓存控制接口和指令来管理和...

    libcurl-ios-dist.zip

    2. 缓存策略:合理设置缓存策略可以提高性能,减少网络请求。 3. 错误排查:遇到问题时,开启libcurl的日志功能,通过日志分析定位问题。 总结,libcurl在iOS开发中提供了一种强大且灵活的网络通信解决方案。了解并...

    Oracle11g-REHL7.2 RAC安装教程

    - **查询不同架构的RPM包版本**:运行`rpm -qa --queryformat "%{NAME}-%{VERSION}-%{RELEASE}(%{ARCH})\n" | grep package_name`以检查软件包版本。 ##### 3.2.2 RHEL 7安装Oracle 11g R2版本要求 - **操作系统包...

    Liunx命令总结全在这里了,几百条.doc

    - `arch`: 显示处理器架构。 - `uname -m`: 同样用于显示处理器架构。 - `uname -r`: 显示当前使用的内核版本。 - `dmidecode -q`: 输出硬件系统部件信息(SMBIOS/DMI)。 - `clock -w`: 将系统时间写入BIOS。 ...

    java外卖ssm项目源码-miaosha:高性能秒杀系统:redis限流+redis缓存+kafka消息队列+mysql乐观锁

    java外卖ssm项目源码 安装和使用说明方法 ...arch: "amd64", family: "unix" 可以使用 mvn clean package打jar包,也可以使用idea自带的package插件进行打包.当然我代码里面已经有已经打好了的包了, 所在的目录为tar

    ebay,youku,facebook等架构文档

    - 高并发场景下的数据库优化策略和读写分离技术。 6. **亚马逊Dynamo** (amazon_dynamo_sosp2007.pdf): - Dynamo是亚马逊的分布式键值存储系统,为电子商务提供了高可用性和可扩展性的解决方案。 - 强调了数据...

    Linux常用命令大全

    1. **`arch`**: 显示机器的处理器架构。 - **用途**: 帮助用户了解系统所基于的处理器类型(如x86_64、i386等),这对于安装特定架构的应用程序或驱动程序非常重要。 2. **`uname -m`**: 显示机器的处理器架构。 ...

Global site tag (gtag.js) - Google Analytics