`
agapple
  • 浏览: 1595496 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

并行加载实施中遇到的问题

阅读更多

背景

  最近着手在一个已有的应用中实施并行加载技术,整理记录一下过程中遇到的问题,方便以后查阅。

 

关于并行加载可以访问:  (业务层)异步并行加载技术分析和设计

 

姊妹篇: (业务层)异步并行加载ChangeLog

 

问题集

1. ThreadLocal不支持 

原理分析: 因为并行加载,导致原先的代码快使用了新的独立的线程进行加载。导致原先代码中使用了ThreadLocal失效。

应用分析: 使用的ThreadLocal有几处地方

 

  *  request/response。 需要在biz层直接操作Http请求对象,web/biz层需要隔离,所以将其包装到ThreadLocal中。 

  *  cache机制。 应用中为了解决权限控制,会一次性通过rpc调用获取remote的权限数据。然后放在ThreadLocal中,web/biz,模板上直接获取ThreadLocal的数据。

  *  重复请求对象。  应用中是一个模块化的设计,为了减少耦合性。两模块直接不允许传递直接数据,但一些会员对象基本每个模块都需要依赖,所以需要进行控制,避免出现重复加载。

解决与否: 已解决,Change 2中已实现

 

2. annotation数据丢失

原理分析:因为并行加载,采用了cglib生成了代理对象,新的class类。

应用分析:一般使用annotation存在几处地方。

 *  参数绑定功能。 现在的MVC框架,包括公司自己的web框架,都喜欢使用在web层进行参数绑定,通过定义一个method参数级的annotation,给定具体的name,框架进行自动注入属性。

 *  spring的一些annotation,比如autowire,transtional等。

 

解决与否: 并不直接正面解决annotaion丢失,而是提供util类允许获取原始的代理对象,从中提取到annotaion信息。

备注: 测试过程中,不仅仅annotation数据丢失,generic泛型信息,field属性都存在丢失。所以针对class对象的一些操作,都是建议直接操作原始class。

 

3. 两次cglib代理,出现final类无法生成代理类

原理分析:因为并行加载,出于性能考虑采用了cglib字节码增强技术。还有一点,jdk代理是依赖必须有接口类,所以综合考虑选择了cglib代理。 

应用分析: final对象存在的几处地方

  *  原先的一些rpc调用,已经通过spring生成了一次代理,部分是使用jdk或者cglib。 通过设置proxyTargetClass=true/false属性。

  *  部分class类,被强制声明为final,避免子类继承

  *  原先应用中部署了一些profile信息,通过拦截器记录一些调用次数和时间等,也是使用了cglib。

 

解决与否: 没办法正面解决,无解的问题。 只能是通过注意使用层面进行规避。

建议的使用: 

 * 使用基于spring advise的并行加载机制,而不是代理整个service。 说白了,就是在原先的代理基础上,新增一个并行加载的拦截器。

 * 使用基于template+callback模板模式的并行加载机制,实现AsyncLoadCallback,传递一代码块。在这代码块中,你可以委托你的service(可能是被cglib代理过的)进行调用。比较嵌入业务

 

4. 缺少默认的构造函数,无法通过newInstance()实例化对象

原理分析:当前一些反射机制

应用分析: 

 *  没有默认的构造函数,新增了自定义的构造函数,特别是在一些model对象。

 

解决与否: 因为如果构造函数中对传递的参数有依赖时,比如进行一些业务判断。目前只是尽可能的去尝试解决,针对带参数的构造函数,尝试给出一些默认值。

 

5. 空指针判断( == )

原理分析: 为实现异步并行加载机制,在调用时会立马返回一个假的返回对象。也就是这个返回对象永远不会为null

应用分析: 

  *  应用中存在比较大量的,在进行一次service调用后,会针对其返回结果进行一次==null判断,避免所谓的NPE。

 

解决与否: 没法从根本上解决该问题,只能是规范和明确并行加载机制的适用范围。建议是:service在model对象默认不为空。

备注:

 *  提供了AsyncLoadUtils.isNull() 替换原先的==null判断方法。有一定的侵入性。

 *  使用AsyncLoadTempalte机制,自定义一个新的并行加载单元,将==null判断包在一个新的AsyncLoadCallback中

 

6. 返回对象为Object,运行过程进行类型强制转化

原理分析: 异步加载,需要在调用时立马返回一个假的对象,会根据当前method的返回值生成代理对象。

应用分析: 

  *  在应用接口中,为了实现所谓的扩展,会以很泛化的Object对象进行结果对象传递。然后通过instanceof在运行时进行强制转化

 

解决与否: 已解决,在扫描到返回对象如果为Object,进行直接调用。 另外:可以通过AsyncLoadTempalte机制,强制指定目标的真实返回对象

 

=========================================2010-04-08更新

7. 并发加载产生的问题: 

异常信息1:

 

Caused by: java.lang.NullPointerException
        at sun.reflect.GeneratedMethodAccessor208.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.alibaba.china.searchengine.dal.dao.search.GeneralSearchImpl$1.intercept(GeneralSearchImpl.java:322)
        at com.alibaba.china.searchengine.dal.dao.dto.OfferSearchResult$$EnhancerByCGLIB$$5dc08842.getComplexResult(<generated>)
        at com.alibaba.kylin.biz.esite.bo.dataprovider.offer.AbstractOfferDataFeeder.searchRecommendOffers(AbstractOfferDataFeeder.java:251)
        at com.alibaba.kylin.biz.esite.bo.dataprovider.winport.AbstractGlareRecOfferDataProvider.getData(AbstractGlareRecOfferDataProvider.java:117)
        at com.alibaba.kylin.biz.esite.bo.dataprovider.winport.GlareRecOffer2DataProvider$$FastClassByCGLIB$$21ffc53c.invoke(<generated>)
        at net.sf.cglib.reflect.FastMethod.invoke(FastMethod.java:53)
        at com.alibaba.kylin.biz.common.dataresolver.FunctionObject.apply(FunctionObject.java:89)
        ... 58 more

 

异常信息2:

Caused by: java.util.ConcurrentModificationException
        at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
        at java.util.AbstractList$Itr.next(AbstractList.java:343)
        at com.alibaba.china.searchengine.dal.dao.search.GeneralSearchImpl$1.intercept(GeneralSearchImpl.java:298)
        at com.alibaba.china.searchengine.dal.dao.dto.OfferSearchResult$$EnhancerByCGLIB$$5dc08842.getComplexResult(<generated>)
        at com.alibaba.kylin.biz.esite.bo.dataprovider.offer.AbstractOfferDataFeeder.searchRecommendOffers(AbstractOfferDataFeeder.java:251)
        at com.alibaba.kylin.biz.esite.bo.dataprovider.winport.AbstractGlareRecOfferDataProvider.getData(AbstractGlareRecOfferDataProvider.java:117)
        at com.alibaba.kylin.biz.esite.bo.dataprovider.winport.GlareRecOffer2DataProvider$$FastClassByCGLIB$$21ffc53c.invoke(<generated>)
        at net.sf.cglib.reflect.FastMethod.invoke(FastMethod.java:53)
        at com.alibaba.kylin.biz.common.dataresolver.FunctionObject.apply(FunctionObject.java:89)
        ... 58 more

 

异常信息3:

Caused by: java.lang.IllegalStateException: Current state = RESET, new state = FLUSHED
        at java.nio.charset.CharsetDecoder.throwIllegalStateException(CharsetDecoder.java:951)
        at java.nio.charset.CharsetDecoder.flush(CharsetDecoder.java:640)
        at java.lang.StringCoding$StringDecoder.decode(StringCoding.java:143)
        at java.lang.StringCoding.decode(StringCoding.java:173)
        at java.lang.StringCoding.decode(StringCoding.java:185)
        at java.lang.String.<init>(String.java:570)
        at java.io.ByteArrayOutputStream.toString(ByteArrayOutputStream.java:163)
        at com.danga.MemCached.SockIOPool$SockIO.readLine(SockIOPool.java:1595)
        at com.danga.MemCached.MemCachedClient.loadItems(MemCachedClient.java:1470)
        at com.danga.MemCached.MemCachedClient.get(MemCachedClient.java:1223)
        at com.danga.MemCached.MemCachedClient.get(MemCachedClient.java:1152)

 

说明:

1. 异常信息1和2,都是因为search的设计引起的。目前search是采用了lazyTask的加载模式,会尝试合并多次查询请求,并将查询请求lazyTask放到ThreadLocal中。而使用了并行加载后,首先多个work thread都能共享这个ThreadLocal,导致多个work thread同时都在处理请求,从而导致各种各样的异常。

2.  StringCoding代码中,使用了ThreadLocal decoder = new ThreadLocal()进行数据对象cache,因为并行加载进行threadLocal共享,所以导致不同线程使用了同一个decoder对象,从而出现线程安全问题。

 

悲剧阿,两个都是因共享ThreadLocal引出来的一个问题。

 

 

 

分享到:
评论

相关推荐

    DATASTAGE并行作业教程

    4. **错误恢复机制**:设计有效的错误检测和恢复机制,确保并行作业在遇到问题时能够快速恢复,避免整个作业失败。 #### 四、并行作业开发步骤 1. **需求分析**:明确数据处理的目标,确定哪些操作可以并行化。 2....

    数据分批加载

    7. 错误处理和恢复:如果在加载过程中遇到问题,需要有适当的错误处理机制,确保可以回溯到上一个成功加载的批次,或者从上次检查点恢复。 在Python编程环境中,可以使用Pandas库的`read_csv`函数配合`chunksize`...

    行业分类-物理装置-一种数据加载方法及装置.zip

    “一种数据加载方法及装置.pdf”可能是详细的技术文档或专利申请,其中可能包含了以下内容:数据加载的流程图、硬件配置建议、性能基准测试、实施步骤、可能遇到的问题及解决方案等。这类文档对于IT从业者,特别是...

    微信小程序分包加载代码实现方法详解

    在实现分包加载时,开发者需要仔细规划小程序的页面结构,合理地组织代码,确保分包后的代码模块之间不存在相互依赖或循环引用的问题。此外,考虑到用户体验,应当尽量减少用户在使用过程中需要下载的分包数量,以...

    spark jdbc 读取并发优化

    1. 根据Long类型字段分区:当表中存在可以作为分区依据的Long类型字段时,比如id字段,我们可以按照该字段的值范围来分布数据。这样可以将整个数据集分散到多个partition中,每个partition由不同的task处理。具体...

    美团通用性能监控平台和WEB性能分析框架

    5. 遇到的瓶颈:演讲中反复提及优化过程中遇到的瓶颈问题,表明美团在性能优化上付出了巨大努力,同时也遇到了许多挑战。突破这些瓶颈通常需要创新的解决方案和技术上的深入分析。 6. 性能优化成效:在演讲中,王...

    OFDM系统的功率加载码本设计

    该技术通过将高速串行数据流转换为多个低速并行子载波的数据流,实现了在频率选择性信道中的高效传输。为了进一步优化OFDM系统的性能,本文提出了一种基于中心极限定理的功率加载码本设计方法,旨在降低平均比特误码...

    基于pytorch实现的yolo_v3

    10. **调试与优化**:在实施过程中,可能会遇到训练不稳定、过拟合等问题,这时可以通过调整学习率、批量大小、数据增强策略等手段进行优化。 本项目提供了完整的YOLOv3实现,包括训练脚本、配置文件、预处理函数等...

    论文研究-商业智能系统构建中的问题及解决方案.pdf

    要建立一个有效的数据仓库,需要对这些数据进行抽取、转换和加载(ETL),这在实施过程中可能会遇到数据一致性、数据准确性以及处理速度的挑战。 解决方案: - 设计灵活的数据抽取策略,允许对不同数据源进行定制化...

    执行的具体过程

    2. **类加载**:当Java虚拟机(JVM)运行程序时,会通过类加载器将需要的类文件加载到内存中。这个过程包括加载、验证、准备、解析和初始化五个阶段。加载阶段查找并导入类,验证确保字节码的安全性,准备为静态变量...

    零售业数据仓库中ETL技术的研究

    - **解决方案**:优化数据加载算法,比如使用并行加载、增量加载等技术;设计完善的错误处理和恢复机制,确保数据加载过程的可靠性。 #### 三、零售业数据仓库中ETL的具体应用 在零售业中,数据仓库主要用于支持...

    数据仓库与数据挖掘技术ETL技术PPT学习教案.pptx

    在设计数据转换时,由于数据源之间往往存在着不一致的问题,因此数据转换必须做到数据名称及格式的统一,同时对于源数据库中可用的信息进行统一。 ETL技术的设计和实施对整个项目的成功至关重要,ETL规则设计和实施...

    Talend open studio 中文使用文档

    在文档的附录部分,通常会记录一个完整的解决方案的诞生过程,包含开发过程中遇到的问题和相应的解决方案。这些内容对于理解如何将Talend Open Studio应用于实际的项目中具有重要价值。 对于新手而言,Talend Open ...

    加载 Javascript 最佳实践

    在网页开发中,JavaScript代码的加载顺序和方式对于页面性能和用户体验有着重大的影响。本文将详细介绍如何根据Yahoo的最佳实践来优化JavaScript的加载,以及随着浏览器技术的发展,我们有哪些新的方法可以选择。 ...

    基于Hadoop的海量数据存储平台设计与开发

    2. **并行加载存储模块**:支持将大量数据并行地加载到Hadoop的分布式文件系统中,同时确保数据的一致性和完整性。 3. **并行查询模块**:利用MapReduce框架来实现高效的数据检索和分析功能,支持复杂查询操作。 4. ...

    海量数据划分内存不足问题解决方法

    在处理海量数据时,经常会遇到由于内存限制导致无法一次性加载全部数据的问题。这种情况下,如何有效地进行数据处理,特别是排序操作,成为了亟需解决的技术难题。本文将针对海量数据排序时内存不足的情况,提出一种...

    关于GPGPU raytracing的一些想法1

    在实施过程中,先开发CPU版本的路径追踪器可以作为调试和验证的基础,当GPU版本遇到困难时,也可以作为回退方案。CPU版本提供了清晰的逻辑和调试途径,有助于理解和优化GPU实现。 最后,阅读和研究SIGGRAPH等专业...

    raykasting:Kotlin中的Ray Casting实施

    Raycasting是一种在计算机图形学中广泛使用的技术,用于在2D平面上渲染3D环境,尤其是在早期的第一人称射击游戏和模拟器中。...遇到性能问题时,可以从算法优化、并行计算和硬件利用等方面寻找解决方案。

    使用kettle实现多表数据全量抽取.rar

    6. **错误处理**:设置错误处理步骤,如错误日志或错误表,以捕获和记录任何导入过程中遇到的问题。 7. **并行执行**:为了提高效率,可以并行运行多个转换,处理不同的表。在工作流中,使用“并行执行”选项来实现...

Global site tag (gtag.js) - Google Analytics