读jedis学对象池

转载于:http://blog.sina.com.cn/s/blog_616e189f0101b12f.html

Apache Commons pool用于提供对象池或者连接池的编写工具,本文简要介绍一下commons pool的主要功能,并以jedis中如何使用commons pool作为例子,加深理解。

根据GenericObjectPool api描述,池的配置如下:

(1)maxActive :表示能够分配的最大对象数目(包括正在被使用的和空闲等待的对象)。为负数时表示对象数目没有上限,默认值为8,当pool维护的对象数目超过maxActive配置的数目,pool的资源被耗尽。

(2)maxIdle:在同一时刻内最多可以维护的空闲对象的数目,默认为8.

(3)whenExhaustedAction:当调用borrow,pool维护的对象超过maxActive时,通过配置将会出现如下动作:

1)WHEN_EXHAUSTED_FAIL borrowObject()将会抛出NoSuchElementException;

2) WHEN_EXHAUSTED_GROW borrowObject()将会继续创建新的对象,并返回,因此,pool维护的对像数将超出maxActive;

3)WHEN_EXHAUSTED_BLOCK,borrowObject()将会阻塞,直到有可用新的或者空闲的object为止,或者如果配置了maxWait,如果请求阻塞超时,将抛出NoSuchElementException. 如果maxWait为负数,请求将会无限制的阻塞下去,默认配置。

(4)testOnBorrow 如果设置,在调用borrowObject方法时,测试对象的可用性(使用PoolableObjectFactory.validateObject(T)方法),如果测试失败,此Object将会从池中删除,取得下一个Object进行测试。默认设置为false(对于链接池,测试对象往往会增加一次网络访问)。

(5)testOnReturn,在returnObject(T)时,会测试对象可用性,与testOnBorrow相似。

对于idle的object,可以设置一定的驱逐策略,让池中尽量保证少的维护对象。需要注意的是,过于频繁的测试驱逐很可能会引发性能问题。配置方法如下:

(1)timeBetweenEvictionRunsMillis 定义驱逐扫描的时间间隔。配置为负值,不需要执行驱逐线程,默认为-1;

(2)minEvictableIdleTimeMillis 确认某个Object空闲超时时间,负值为永远不超时,在驱逐线程清理超时对象时,只有空闲时间超过minEvictableIdleTimeMillis的对象才会被清除,默认为30分钟;

(3)testWhileIdle 对idle的Object进行验证,无效的Object将会从池中删除;

(4)softMinEvictableIdleTimeMillis 在驱逐时,可以预留一定数量的idle 对象,是minEvictableIdleTimeMillis的一个附加条件,如果为负值,表示如果驱逐,则所有idle对象都被驱逐;

(5)numTestsPerEvictionRun 一次驱逐过程中,最多驱逐对象的个数;

对象队列有两种,一种是LIFO(last in first out)和FIFO(First in first out),可以选择两种之一。(注:对象在pool中实际是以队列的形式存在的,按照一定策略,在对象借出或者归还时插入队列的不同位置)

Lifo用于设置策略,默认为true。

下面,我们从jedis中拿出池代码,来看看池是如何使用的。

1.     池factory(JedisPool.java)

private static class JedisFactory extends BasePoolableObjectFactory {

private final String host;

private final int port;

private final int timeout;

private final String password;

private final int database;

public JedisFactory(final String host, final int port,

final int timeout, final String password, final int database) {

super();

this.host = host;

this.port = port;

this.timeout = timeout;

this.password = password;

this.database = database;

}

public Object makeObject() throws Exception {

final Jedis jedis = new Jedis(this.host, this.port, this.timeout);

jedis.connect();

if (null != this.password) {

jedis.auth(this.password);

}

if( database != 0 ) {

jedis.select(database);

}

return jedis;

}

public void destroyObject(final Object obj) throws Exception {

if (obj instanceof Jedis) {

final Jedis jedis = (Jedis) obj;

if (jedis.isConnected()) {

try {

try {

jedis.quit();

catch (Exception e) {

}

jedis.disconnect();

catch (Exception e) {

}

}

}

}

public boolean validateObject(final Object obj) {

if (obj instanceof Jedis) {

final Jedis jedis = (Jedis) obj;

try {

return jedis.isConnected() && jedis.ping().equals("PONG");

catch (final Exception e) {

return false;

}

else {

return false;

}

}

}

}

对象池工厂,继承与BasePoolableObjectFactory,并重写相应方法。

2.     池的实现

在jedis的Pool.java中,有如下代码:

public Pool(finalGenericObjectPool.Config poolConfig,

PoolableObjectFactory factory) {

this.internalPool = new GenericObjectPool(factory, poolConfig);

}

@SuppressWarnings("unchecked")

public T getResource() {

try {

return (T) internalPool.borrowObject();

catch (Exception e) {

throw new JedisConnectionException(

"Could not get a resource from the pool", e);

}

}

public void returnResourceObject(final Object resource) {

try {

internalPool.returnObject(resource);

catch (Exception e) {

throw new JedisException(

"Could not return the resource to the pool", e);

}

}

3.     我们使用如下方法,创建池,获取池资源,返回池资源

Config config = new Config();

config.maxActive = 20;

JedisPool pooles = new JedisPool(config, "10.4.21.51", 6379);

Jedis jedis = pooles.getResource();

List rets = jedis.lrange("999", 1000000000000999990L, 1000);

pooles.returnResource(jedis);

4.     小结

GenericObjectPool的构造函数有两个参数,一个是Config,一个是PoolableObjectFactory,其中Config用于配置我们前面提到的参数选项,而PoolableObjectFactory则是实际创建对象,验证对象,销毁对象等的实际操作。

在我们的例子中,config仅设置了maxActive,即最大的可用Object数目,每创建一个Object,jedis就会创建一个与redis的链接,因此控制maxActive是必要的;当调用borrowObject()资源耗尽时,请求会排队并且maxwait值为-1,表示永远等待下去;timeBetweenEvictionRunsMillis默认为-1,因此,没有驱逐策略;lifo默认为true,因此使用last in first out 策略。

时间: 2024-10-29 02:43:26

读jedis学对象池的相关文章

大数据技术之_27_电商平台数据分析项目_02_预备知识 + Scala + Spark Core + Spark SQL + Spark Streaming + Java 对象池

第0章 预备知识0.1 Scala0.1.1 Scala 操作符0.1.2 拉链操作0.2 Spark Core0.2.1 Spark RDD 持久化0.2.2 Spark 共享变量0.3 Spark SQL0.3.1 RDD.DataFrame 与 DataSet0.3.2 DataSet 与 RDD 互操作0.3.3 RDD.DataFrame 与 DataSet 之间的转换0.3.4 用户自定义聚合函数(UDAF)0.3.5 开窗函数0.4 Spark Streaming0.4.1 Dst

对象池实现分析

对象池实现分析 什么是对象池技术?对象池应用在哪些地方? 对象池其实就是缓存一些对象从而避免大量创建同一个类型的对象,类似线程池的概念.对象池缓存了一些已经创建好的对象,避免需要时才创建对象,同时限制了实例的个数.池化技术最终要的就是重复的使用池内已经创建的对象.从上面的内容就可以看出对象池适用于以下几个场景: 创建对象的开销大 会创建大量的实例 限制一些资源的使用 如果创建一个对象的开销特别大,那么提前创建一些可以使用的并且缓存起来(池化技术就是重复使用对象,提前创建并缓存起来重复使用就是池化

Netty轻量级对象池实现分析

什么是对象池技术?对象池应用在哪些地方? 对象池其实就是缓存一些对象从而避免大量创建同一个类型的对象,类似线程池的概念.对象池缓存了一些已经创建好的对象,避免需要时才创建对象,同时限制了实例的个数.池化技术最终要的就是重复的使用池内已经创建的对象.从上面的内容就可以看出对象池适用于以下几个场景: 创建对象的开销大 会创建大量的实例 限制一些资源的使用 如果创建一个对象的开销特别大,那么提前创建一些可以使用的并且缓存起来(池化技术就是重复使用对象,提前创建并缓存起来重复使用就是池化)可以降低创建对

(转载)一个通用并发对象池的实现

原文链接,译文链接,原文作者: Sarma Swaranga,本文最早发表于deepinmind,校对:郑旭东 这篇文章里我们主要讨论下如何在Java里实现一个对象池.最近几年,Java虚拟机的性能在各方面都得到了极大的提升,因此对大多数对象而言,已经没有必要通过对象池来提高性能了.根本的原因是,创建一个新的对象的开销已经不像过去那样昂贵了. 然而,还是有些对象,它们的创建开销是非常大的,比如线程,数据库连接等这些非轻量级的对象.在任何一个应用程序里面,我们肯定会用到不止一个这样的对象.如果有一

用Java实现一个通用并发对象池

这篇文章里我们主要讨论下如何在Java里实现一个对象池.最近几年,Java虚拟机的性能在各方面都得到了极大的提升,因此对大多数对象而言,已经没有必要通过对象池来提高性能了.根本的原因是,创建一个新的对象的开销已经不像过去那样昂贵了. 然而,还是有些对象,它们的创建开销是非常大的,比如线程,数据库连接等这些非轻量级的对象.在任何一个应用程序里面,我们肯定会用到不止一个这样的对象.如果有一种很方便的创建管理这些对象的池,使得这些对象能够动态的重用,而客户端代码也不用关心它们的生命周期,还是会很给力的

java/android 设计模式学习笔记(5)---对象池模式

这次要介绍一下对象池模式(Object Pool Pattern),这个模式为常见 23 种设计模式之外的设计模式,介绍的初衷主要是在平时的 android 开发中经常会看到,比如 ThreadPool 和 MessagePool 等. 在 java 中,所有对象的内存由虚拟机管理,所以在某些情况下,需要频繁创建一些生命周期很短使用完之后就可以立即销毁,但是数量很大的对象集合,那么此时 GC 的次数必然会增加,这时候为了减小系统 GC 的压力,对象池模式就很适用了.对象池模式也是创建型模式之一,

对象池学习

概念 为了避免大量创建(构造)对象.销毁(析构)对象带的性能开销 设计 对象队列 初始化时,指定队列长度 出队.入队操作需要加锁保护 对象的构造 在初始化对象池时构造好 对象并不是一开始全部构造好,而是在获取对象的过程中构造(构造之后便保存在队列中供使用) 获取对象 提供接口 归还对象 提供接口,显示归还 利用c++ RAII特性(即智能指针析构时,调用归还操作),隐式归还 对象管理器 负责构造对象与销毁对象 管理每个对象的状态 获取状态接口 提供接口,用户可以获取对象池的各种状态信息 注意事项

Unity程序优化之对象池

对于做程序的朋友来说优化是一个避免不了的话题,对于程序的优化可以从两个方面来入手,一个是CPU方面的优化,一个是GPU的优化.对于CPU与GPU的作用简单理解的话你可以暂时当做CUP是处理计算的.GPU是处理渲染的,例如程序中的一些计算啊逻辑处理啊都是有CPU来处理的,,我们程序的显示啊,特效等一切看到的东西都是GPU来处理的.当然他们的关系不单单如此,扯远了哈,我们这篇博客主要讲CPU优化方面的对象池技术.对象池大家应该都听说过,它主要应用于处理需要大量重复利用的资源的,因为如果有很多资源如果

整数对象池

Python 的内建对象存放在源代码的Objects目录下.intobject.c用于整数对象 在 Python 中,整数分为小整数对象和大整数对象 小整数对象 由于数值较小的整数对象在内存中会很频繁地使用,如果每次都向内存申请空间.请求释放,会严重影响 Python 的性能.好在 整数对象 属于不可变对象,可以被共享而不会被修改导致问题,所以为 小整数对象 划定一个范围,即小整数对象池,在Python运行时初始化并创建范围内的所有整数,这个范围内的 整数对象是被共享的,即一次创建,多次共享引用