`
lvhuiqing
  • 浏览: 253299 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

2.5. Liveness and Performance(存活性和性能)

阅读更多
2.5. Liveness and Performance(存活性和性能)
In UnsafeCachingFactorizer, we introduced some caching into our factoring servlet in the hope of improving performance. Caching required some shared state, which in turn required synchronization to maintain the integrity of that state. But the way we used synchronization in SynchronizedFactorizer makes it perform badly. The synchronization policy for SynchronizedFactorizer is to guard each state variable with the servlet object's intrinsic lock, and that policy was implemented by synchronizing the entirety of the service method. This simple, coarse-grained approach restored safety, but at a high price.
UnsafeCachingFactorizer类中,为了能够改进性能,我们向因式分解servlet中增加了缓存机制。缓存需要状态共享,这就需要同步机制来维护状态的一致性。但是SynchronizedFactorizer中,我们的同步使用方式导致执行性能很差。SynchronizedFactorizer类的同步策略是使用servlet对象的内在锁来进行同步,并且通过把整个service方法变成同步方法来实现。虽然这样做可以很轻易的就达到实现安全的目标,但却付出了极大的代价。
Because service is synchronized, only one thread may execute it at once. This subverts the intended use of the servlet framework that servlets be able to handle multiple requests simultaneously and can result in frustrated users if the load is high enough. If the servlet is busy factoring a large number, other clients have to wait until the current request is complete before the servlet can start on the new number. If the system has multiple CPUs, processors may remain idle even if the load is high. In any case, even short-running requests, such as those for which the value is cached, may take an unexpectedly long time because they must wait for previous long-running requests to complete.
由于service方法是同步的,在同一个时刻只有一个线程可以执行该方法。这就颠覆了servlet框架推荐的使用方式:可以同时处理多个用户请求。在负载很高情况下,这将导致用户体验极差。如果servlet在忙于分解一个很大的数值的时候,另外一个客户端必须等待,直到分解结束才能开始分解下一个请求。如果系统拥有多个cpu的时候,即使负载很高,处理器也可能会出现空闲状态。即使是很简短的请求,比如那些值已经被缓存的情况下,也会等待很长时间,因为他们必须等待前一个请求被执行结束。
图2.1展示了当多个请求到达同步因数分解servlet的时候会发生什么事情,他们将会排队等待处理时序。我们可以把这个web应用作为差并发性的一个典型例证:能够同时处理请求的数量并不是由硬件资源限制的,而是由软件架构本身限制。幸运的是,通过把同步块变窄可以改善该servlet的并发性能。你要注意不要把同步块的范围变得过窄。你可能不会想把一个本来应该是原子的操作分解到多个同步块中。但是尽量将需要长时间执行的操作从同步块中排除出来是非常合乎情理的。这样一来,其他线程就不会被访问该常运行的线程阻止。
Figure 2.1. Poor Concurrency of SynchronizedFactorizer.
CachedFactorizer in Listing 2.8 restructures the servlet to use two separate synchronized blocks, each limited to a short section of code. One guards the check-then-act sequence that tests whether we can just return the cached result, and the other guards updating both the cached number and the cached factors.
As a bonus, we've reintroduced the hit counter and added a "cache hit" counter as well, updating them within the initial synchronized block. Because these counters constitute shared mutable state as well, we must use synchronization everywhere they are accessed. The portions of code that are outside the synchronized blocks operate exclusively on local (stack-based) variables, which are not shared across threads and therefore do not require synchronization.
Listing 2.8中的CachedFactorizer类把servlet重新用同步块划分。每一个限制到一段很短的代码中。其中一个代码块守护用来判断是否只是需要返回被缓存结果的“check-then-act”时序。而另外一个代码块则是用来更新被缓存的数值和因数。另外,我们重新定义了“点击计数”并且增加了一个“缓存计数”,这两个计数将会在静态初始化块中被初始化。由于这两个计数会建立共享的可变状态,因此在他们被访问的任何地方必须使用同步机制。在同步代码块之外的代码部分只会操作本地变量,这种变量不会被线程间共享,因此不需要同步机制。
Listing 2.8. Servlet that Caches its Last Request and Result.
@ThreadSafe
public class CachedFactorizer implements Servlet {
    @GuardedBy("this") private BigInteger lastNumber;
    @GuardedBy("this") private BigInteger[] lastFactors;
    @GuardedBy("this") private long hits;
    @GuardedBy("this") private long cacheHits;

    public synchronized long getHits() { return hits; }
    public synchronized double getCacheHitRatio() {
        return (double) cacheHits / (double) hits;
    }

    public void service(ServletRequest req, ServletResponse resp) {
        BigInteger i = extractFromRequest(req);
        BigInteger[] factors = null;
        synchronized (this) {
            ++hits;
            if (i.equals(lastNumber)) {
                ++cacheHits;
                factors = lastFactors.clone();
            }
        }
        if (factors == null) {
            factors = factor(i);
            synchronized (this)  {
                lastNumber = i;
                lastFactors = factors.clone();
            }
        }
        encodeIntoResponse(resp, factors);
    }
}

CachedFactorizer no longer uses AtomicLong for the hit counter, instead reverting to using a long field. It would be safe to use AtomicLong here, but there is less benefit than there was in CountingFactorizer. Atomic variables are useful for effecting atomic operations on a single variable, but since we are already using synchronized blocks to construct atomic operations, using two different synchronization mechanisms would be confusing and would offer no performance or safety benefit.
CachedFactorizer类不再需要AtomicLong类作为“点击计数”而是采用一个长整型域。这里也可以使用AtomicLong类,但是使用这个类带来的好处没有在CountingFactorizer类中使用这个类明显。Atomic变量类型对于单个变量的原子操作来说是有效率的,但是由于我们已经使用来同步代码块来构建原子请求,那么使用两种同步机制可能会带来不必要的混淆,而不会带来性能和安全性的提高。
The restructuring of CachedFactorizer provides a balance between simplicity (synchronizing the entire method) and concurrency (synchronizing the shortest possible code paths). Acquiring and releasing a lock has some overhead, so it is undesirable to break down synchronized blocks too far (such as factoring ++hits into its own synchronized block), even if this would not compromise atomicity. CachedFactorizer holds the lock when accessing state variables and for the duration of compound actions, but releases it before executing the potentially long-running factorization operation. This preserves thread safety without unduly affecting concurrency; the code paths in each of the synchronized blocks are "short enough".
CachedFactorizer类的重构在并发性和简单性两个方面取得了平衡。请求和释放锁是需要一些负荷的,所以即使不会破坏原子性,也不要把同步块分解的过细。CachedFactorizer类访问状态变量的时候或者访问符合行为的时候会持有锁,会在有可能需要长时间执行的因式分解操作是释放锁。这就在不会影响并发性能的时候保证了线程安全。同步块中的代码长度也就“足够短”了。
Deciding how big or small to make synchronized blocks may require tradeoffs among competing design forces, including safety (which must not be compromised), simplicity, and performance. Sometimes simplicity and performance are at odds with each other, although as CachedFactorizer illustrates, a reasonable balance can usually be found.
具体将同步块变成多长需要在几个同等重要的元素之间:安全、简易性、性能之间作出权衡。尽管可以像CachedFactorizer类中描绘的那样在简易性和性能上可以取得一些平衡但有时候,简易性和性能是不匹配的。
There is frequently a tension between simplicity and performance. When implementing a synchronization policy, resist the temptation to prematurely sacriflce simplicity (potentially compromising safety) for the sake of performance.
简单性和性能上存在某种对立。当实现同步策略的时候,应该避免为了追求性能而牺牲简单性(这有可能会隐藏线程不安全元素)。
Whenever you use locking, you should be aware of what the code in the block is doing and how likely it is to take a long time to execute. Holding a lock for a long time, either because you are doing something compute-intensive or because you execute a potentially blocking operation, introduces the risk of liveness or performance problems.
不管什么时候,如果你需要用到锁,你都应该注意阻塞块中的代码行为以及它们大约的运行时间。不管是在进行集中的计算还是在执行潜在的阻塞操作,长时间的持有锁都会带来存活性和性能问题。
Avoid holding locks during lengthy computations or operations at risk of not completing quickly such as network or console I/O.
应该在网络或者控制台IO过程中,避免长时间的持有锁。


0
0
分享到:
评论

相关推荐

    liveness and safetiy properties

    在计算机科学领域,特别是软件工程与系统验证方面,**活动性(Liveness)**和**安全性(Safety)属性**是两个核心概念,用于描述系统的行为特性。这两种属性对于确保系统的正确性和可靠性至关重要。本文将基于提供的...

    Void A fast and light voice liveness detection system.pdf

    这项技术通过评估两个数据集的性能来展示其有效性:一个是由120名参与者、15个播放设备和12个录音设备生成的255,173个声音样本,另一个是由42名参与者、26个播放设备和25个录音设备生成的18,030个公开可用的声音样本...

    A New Multispectral Method for Face Liveness Detection.

    传统的头部检测方法通常依赖于形状和颜色特征,然而这些特征对于照片、模仿面具以及商场中的人体模型来说非常相似,从而导致了误检的可能性增加。因此,需要一种更加有效的后处理步骤——即人脸活性检测方法——来...

    k8s – livenessProbe – tcp存活性检测

    [root@k8s-master01 k8s-test]# cat livenessProbe-tcp.yaml apiVersion: v1 kind: Pod metadata: name: liveness-tcp namespace: default spec: containers: - name: liveness-tcp-container image: kone....

    Liveness-Detection-(AndroidX).zip

    它提供了对Android API的兼容性支持,同时引入了许多新特性和改进,让开发者能更好地掌控项目的架构和性能。AndroidX库包含了许多用于UI、数据存储、测试等方面的功能模块,而活体检测正是其中的一个重要组成部分。 ...

    K8S – livenessProve – 存活性探测

    [root@k8s-master01 k8s-test]# cat liveness.yaml apiVersion: v1 kind: Pod metadata: name: liveness-exec-pod namespace: default spec: containers: - name: liveness-exec-container image: kone....

    hadoop 2.9.0 yarn-default.xml 属性集

    Hadoop是一个开源的分布式存储和计算框架,它允许用户存储大量数据并进行分布式计算。Hadoop 2.9.0版本中的YARN(Yet ...配置YARN的属性集是实现这些目标的基础工作,对于Hadoop集群的性能和安全性有着直接的影响。

    Liveness-Detection(android.support) (1).zip

    本压缩包“Liveness-Detection(android.support) (1).zip”提供了一个高级的活体检测Android SDK,版本号为V1.3.3,它专门设计来增强应用程序的安全性和用户体验。 SDK(Software Development Kit)是软件开发者...

    Liveness-Detect:最简单的实时人脸识别API

    Python的易读性和广泛支持使得这个API易于理解和扩展。 3. **Django REST框架** Django是Python的一款流行Web开发框架,而REST(Representational State Transfer)是一种网络应用程序的设计风格,常用于构建可...

    FaceLivenessDetection.zip_live detectness_liveness_moonml3_活体人脸_

    《人脸活体检测技术详解与应用》 在现代信息技术领域,人脸识别技术已经广泛应用于安全监控、身份...通过深入理解和运用其中的算法,我们可以更好地应对现实世界中的安全挑战,提升人工智能系统的智能水平和可靠性。

    动态纹理人脸活体检测

    由于面部信息在身份验证和识别中的流行,生物识别领域已经成为计算机视觉研究中最活跃和最具挑战性的领域之一。尽管人脸识别技术在过去几十年中取得了显著进步,但不同视角、主体老化以及复杂户外照明等问题仍然是...

    LCPD.zip_LCPD_descriptor_image processing_liveness detection_pha

    在计算机视觉领域,图像处理和生物识别技术是至关重要的部分,而“局部对比相位描述符”(Local Contrast Phase Descriptor,简称LCPD)正是其中的一种创新方法,尤其在活体检测(liveness detection)中表现出色。...

    Everything I Learned About Scaling Online Games I Learned at Google and eBay

    Scalability and Performance Small Details Matter eBay Search Index Compression TOME Combat Server Measurement and Distributions How to Scale - Scaling DevOps Automate Everything Autoscaling App Engine...

    healthchex:一组用于 Kubernetes 健康检查的 Plugs

    Kubernetes Liveness 和 Readiness Probes 作为 Elixir Plugs。 安装 可以通过将healthchex添加到中的依赖项列表来安装该软件包: def deps do [ { :healthchex , " ~> 0.2 " } ] end 用法 为了使文档保持最新...

    liveness_src.zip

    内部排序:如果整个排序过程不需要借助外部存储器(如磁盘等),所有排序操作都是在内存中完成,这种排序就被称为内部排序。 就常用的内部排序算法来说,可以分为以下几类: * 选择排序(直接选择排序,堆排序) ...

    A Reduction Method of Analyzing Data-Liveness and Data-Boundedness for a Class of E-commerce Business Process Nets

    业务流程的安全行为特性,例如数据活跃性(data-liveness)和数据界限性(data-boundedness),在电子商务业务流程中尤为重要。数据活跃性涉及到数据项在业务流程中是否能够持续得到处理和更新;而数据界限性则关注...

    行业分类-物理装置-一种实现容器应用可用性定时探测的方法.zip

    2. Kubernetes的探测机制:Kubernetes扩展了健康检查的概念,包括就绪探针(readiness probe)和存活探针(liveness probe)。就绪探针确保容器已准备好接收流量,而存活探针则用于确定何时重启不健康的容器。这些...

    Efficient MIDP Programming

    The main goal of this document is to outline best practices for optimizing performance, resource usage, and perceived user experience in MIDP applications. By following these guidelines, developers ...

    aws-liveness:AWS Liveness工具

    鲜活AWS Liveness工具。安装 npm i --save aws-liveness用法 const AWSLiveness = require ( 'aws-liveness' ) ;const { DynamoDB } = require ( 'aws-sdk' ) ;const awsLiveness = new AWSLiveness ( ) ;const ...

Global site tag (gtag.js) - Google Analytics