storm中几个小技巧

storm 中小技巧

1、 TimeCacheMap过期缓存,采用桶实现,锁的粒度小,O(1)时间内完成锁操作,因此,大部分时间内都可以进行get和put操作。几乎所有的操作都是相对于桶数目线性的(O(numBuckets))。唯一的问题是缓存中可能存在过期的数据,也就是说真正的超时时间介于expirationSecs和expirationSecs * (1 + 1 / (numBuckets-1))之间。

 public TimeCacheMap(int expirationSecs, int numBuckets, ExpiredCallback<K, V> callback) {
        if(numBuckets<2) {
            throw new IllegalArgumentException("numBuckets must be >= 2");
        }
        _buckets = new LinkedList<HashMap<K, V>>();
        for(int i=0; i<numBuckets; i++) {
            _buckets.add(new HashMap<K, V>());
        }


        _callback = callback;
        final long expirationMillis = expirationSecs * 1000L;
        final long sleepTime = expirationMillis / (numBuckets-1);
        _cleaner = new Thread(new Runnable() {
            @SuppressWarnings("unchecked")
			public void run() {
                try {
                    while(true) {
                        Map<K, V> dead = null;
                        Time.sleep(sleepTime);
                        synchronized(_lock) {
                            dead = _buckets.removeLast();
                            _buckets.addFirst(new HashMap<K, V>());
                        }
                        if(_callback!=null) {
                            for(Entry<K, V> entry: dead.entrySet()) {
                                _callback.expire(entry.getKey(), entry.getValue());
                            }
                        }
                    }
                } catch (InterruptedException ex) {

                }
            }
        });
        _cleaner.setDaemon(true);
        _cleaner.start();
    }
2. 对元组的序列化采用kryo,并且使用了动态池的概念。这样避免了大量对象创建和销毁的开销,增加了效率

public class ThreadResourceManager<T> {
    public static interface ResourceFactory<X> {
        X makeResource();
    }
    
    ResourceFactory<T> _factory;
    ConcurrentLinkedQueue<T> _resources = new ConcurrentLinkedQueue<T>();
    
    public ThreadResourceManager(ResourceFactory<T> factory) {
        _factory = factory;
    }
    
    public T acquire() {
        T ret = _resources.poll();
        if(ret==null) {
            ret = _factory.makeResource();
        }
        return ret;
    }
    
    public void release(T resource) {
        _resources.add(resource);
    }
}
3. 对于supervisor进程和worker进程都在本地保存一个kv库,用于同步。kv实现为LocalState,一个基于map实现, 每次读写都需要直接操作磁盘的简单数据库。每次put数据时都要序列化数据,在序列化数据过程中,为了同步和原子性,采用了VersionedStore类,就是每次更新过程中不会去update现有的文件, 而是不断的产生递增version的文件, 故每一批更新都会产生一个新的文件。
 VersionedStore类中采用两种文件实现原子性和同步性:
VersionFile, _root + version, 真正的数据存储文件 
TokenFile, _root + version + “.version”, 标志位文件, 标志version文件是否完成写操作, 以避免读到正在更新的文件 

private void persist(Map<Object, Object> val, boolean cleanup) throws IOException {
    byte[] toWrite = Utils.serialize(val);//序列化要写入的数据 
    String newPath = _vs.createVersion();//创建新的versionfile的path
    FileUtils.writeByteArrayToFile(new File(newPath), toWrite);//数据写入versionfile 
    _vs.succeedVersion(newPath);//调用succeedVersion, 创建tokenfile以标志versionfile的写入完成 
    if(cleanup) _vs.cleanup(4);//清除旧版本, 只保留4个版本
}
4. 待续







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值