获取数据库序列
林小应
1.问题描述
由于业务需要,应用程序中很多地方会用到数据库序列sequence,如果每次都去数据库获取,会比较耗时。
在Java代码中,我们通常调用存储过程或执行sql生成一个sequence,如
select xxx.nextnvl from dual;
如果直接调用存储过程或执行sql取sequence,算上事务开销,一次需要3~4ms。在大型分布式系统中(如江苏电信的营业系统、淘宝网、大型社交网站),4ms将是一个很大的开销,试想如果需要的序列已经存储在于内存中,平均每次取sequence的时间损耗将低于0.01ms。
2.期望
避免每次前往数据库取序列,让获取sequence就像从内存中取一个对象一样简单、决不允许重复读取。
3.设计原理
获取sequence的Java代码类似如下:
String seq = generateSeq(String seqType);
输入参数:seqType
输出参数:sequence
我的思路是:在内存中开辟一个大容器(HashMap),存放各种seqType的sequence队列(Queue)。由一个守护线程来完成队列的装填。
当第一次取某种类型的sequence,在容器中注册一下,记录下seqType。这样守护线程就能察觉到,守护线程不断检测所有类型的sequence队列。如果容量不足,就会启动装填机制,从数据获取一批新的sequence将空队列装满。
4. 实现
具体实现过程需要保证,多线程环境中资源锁的问题。这里我们用的HashMap是ConcurrentHashMap,是一种线程安全的高性能Map。Map中的seqType所对应的“sequence队列”,已经换成了队列组、即一个ArrayList中存放多个sequence队列。这样主要是为了降低并发带来的开销。
根据入参seqTypeA,首先取到的是一个ArrayList<ConcurrentLinkedQueue>,再根据ArrayList的size随机一个整数cur,再取ArrayList中第cur个sequence队列。并发压力和size的大小成反比!
示意图:
5. JVM序列池的生命周期
序列池的生命周期为:第一次注册 到 应用程序终止
6. 需要注意的问题
A. 不能读到脏数组,一个sequence不能被两次读到。上面我们的sequence都是从数据库来,保存在同步队列ConcurrentLinkedQueue中,这一点可以保证。
B. sequence的顺序,如果从数据库直接读取顺序是一致的。采用sequence池机制,可能后面读到的比前面读到的小/大。我们可以将上面的ArrayList的size设置成1就可以解决顺序问题(不使用于分布式环境)。
C.命中率问题,如果sequence池空了,主线程就会直接前往数据库。为了提高命中率,我们的系统中采用了备用池——主池空了以后,立即从备用池拉一个现成的队列替换当前队列(这个非常有效)。
D.灵活的配置,如队列池的深度(队列的长度)、宽度(ArrayList的size)、实时的开关机制等
7. 总结
以上只能简单说一下,我们对于这种频繁获取sequence情况的解决方案。我们的系统是40000000用户,分布式系统,多数据库。采用了sequence池机制以后,获取sequence的时间大大缩短了。
还有很多细节,大家动手做的时候再慢慢琢磨。
qq:346420558
分享到:
相关推荐
customerID 顾客编号 自动编号(标识列),从1开始,主键 用序列sequence实现,用其属性:nextval customerName 开户名 必填 PID 身份证号 必填,智能是18位或15位,唯一约束 check约束length()函数 telephone 联系...
在Oracle数据库中,sequence等同于序列号,每次取的时候sequence会自动增加,一般会作用于需要按序列号排序的地方。 1、Create Sequence (注释:你需要有CREATE SEQUENCE或CREATE ANY SEQUENCE权限) CREATE ...
Oracle数据库表序列ID自增生成器的功能是为数据库中的表添加序列和触发器,以便使数据表的主键ID能够随着记录的增加而自动增加。
顺序从数据库生成序列 ID
京东金融数据库开发管理规范-SEQUENCE,,适用者为DBA,系分,开发和项目经理,用于规范数据库SEQUENCE开发设计流程
基于数据库的分布式发号器-viemall-sequence基于数据库的分布式发号器-viemall-sequence基于数据库的分布式发号器-viemall-sequence基于数据库的分布式发号器-viemall-sequence基于数据库的分布式发号器-viemall-...
———————————————————————————————————————————————— 此处使用的数据集包含每个手写单词的图像,并以短划线分隔的文件名格式。 第一个字段代表单词id,第二个字段...
Matlab产生m序列的函数-m_sequence1.m 一个产生m序列的函数,希望大家喜欢 function [mseqmatrix]= m_sequence1; n = length; N = 2^n-1; register = [zeros 1];%定义移位寄存器的初始状态 mseqmatrix= ...
TUD的行人检测数据库,tud-crossing-sequence图像序列。
可以根据oracle数据库中存在的sequence,生成建立语句
REVERSING THE TRAIL SEQUENCE ————— 104 PARAMETERS ———— 107 GLOBALS PARAMETERS 109 MANAGER PARAMETERS ———— 110 EXTRACT PARAMETERS———— 113 REPLICAT PARAMETERS ———— 122 DATA MAPPING ...
数据库系统原理 实验报告 实验名称:关系数据库完整性实验 任课教师:霍纬刚 学号:100341324 姓名:汪何媛 完成日期:2012.11.28 1. 实验目的 通过ORACLE的完整性,理解关系数据库的完整性 2. 实验内容与步骤 ...
在Oracle数据库移植过程中,sequence可能失效,本资源可使失效的sequence重新恢复作用
全局子序列比对 Global Sequence Alignment
1 3 命名规范 3 3.1 数据库命名规则 3 3.2 数据库对象命名的一般原则 4 3.3 表空间(Tablespace)命名规则 4 3.4 表(Table)命名规则 4 3.5 字段命名规则 5 3.6 视图(View)命名规则 5 3.7 序列(Sequence)命名规则 5 3.8...
因此,对于关系型数据库而言——Entity和Query是一体两面的事物,所谓Query,可以包含各种复杂的查询条件,甚至可以作为一个完整的SQL操作请求的描述。为此,EF彻底将Entity和Query绑在了一起。这种思想,使得...
生成5,6,7阶m序列,并选择最优序列对生成Gold序列
在ORACLE数据库中,序列(SEQUENCE)是使用非常频繁的一个数据库对象,但是有时候会遇到序列(SEQUECNE)跳号(skip sequence numbers)的情形,那么在哪些情形下会遇到跳号呢? 事务回滚引起的跳号 不管序列有...
SARSCoV2-全局序列分布GISAID数据库上SARS-CoV-2序列的全球分布回购中的文件夹输入=分析所需的所有输入数据。 输出=输出文件:人均序列与人均GDP的气泡图(也作为交互式html)和已处理数据的csv文件。 代码= R脚本。...
1 3 命名规范 3 3.1 数据库命名规则 3 3.2 数据库对象命名的一般原则 4 3.3 表空间(Tablespace)命名规则 4 3.4 表(Table)命名规则 4 3.5 字段命名规则 5 3.6 视图(View)命名规则 5 3.7 序列(Sequence)命名规则 5 3.8...