大数据下高并发的处理详解_第1页
大数据下高并发的处理详解_第2页
大数据下高并发的处理详解_第3页
大数据下高并发的处理详解_第4页
大数据下高并发的处理详解_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、大数据下高并发的处理详解作者:日期:?大数据下高并发的处理详解本文章来自于阿里云云栖社区对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了。而并发问题是绝大部分的程序员头疼的问题,但话又说回来了,既然逃避不掉,那我们就要想想应对措施,今天我们就一起讨论一下常见的并发和同步吧。首先为了更好的理解并发和同步,我们需要首先明白两个重要的概念:同步和异步同步和异步的区别和联系所谓同步, 就是一个线程执行一个方法或函数的时候,会阻塞其它线程,其他线程要等待它执行完毕才能继续执行。异步,就是多个线程之间没有阻塞,多个线程同时执行。通俗一点来说,同步就是一件事一件事的做,

2、异步就是做一件事,不影响做其他事情。例如 :吃饭和说话 ,只能一件一件的来,因为只有一张嘴。?但是吃饭和听音乐是异步的,可以一起进行,因为听音乐并不影响我们吃饭。对于 java 程序员来说 ,syn h o ized最为熟悉了 ,如果它作用于一个类的话,那么就是一个线程访问类的方法时,其他线程就会阻塞,相反 ,如果没有这个关键字来修饰的话,不同线程就可以在同一时间访问同一个方法,这就是异步。脏读和不可重复读脏读脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中 ,这是 ,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外

3、一个事务读取的这个数据是脏数据( rty ta), 依据脏数据所做的操作可能是不正确的。不可重复读 ?在第一个事务读取数据后,第二个事务对数据进行了修改,导致第一个事务结束前再访问这个数据的时候,会发现两次读取到的数据是不一样的,因此称为不可重复读。如何处理并发和同步?今天讲的如何处理并发和同同步问题主要是通过锁机制。?我们需要明白,锁机制有两个层面。一种是代码层次上的,如果ava 中的同步锁synch onized ,另一种是数据库层次上的,比较典型的就是悲观锁 (传统的物理锁 )和乐观锁悲观锁悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理 )修

4、改持保守态度。因此,在这个数据处理过程中,将数据处于锁定状态。悲观锁的实现 ,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则 ,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。一个典型的倚赖数据库的悲观锁调用:s ect*f o ntw er nam =”e ica ” orupd e这条 q 语句锁定了account表中所有符合检索条件( nam = ”ric ” )的记录。本次事务提交之前(事务提交时会释放事务过程中的锁), 外界无法修改这些记录。?hibernate的悲观锁 ,也是基于数据库的锁机制实现。?下面的代码实现了对查询记

5、录的加锁 :1? str nghql r = from t ser asuse where us r n e=erica;?q2 ery uery es ion c eatequ ry(h lst ) ;3qu ry .setl ck ode ( u , lockmode.upgr de) ; 加锁 ?listuserl4i t = uer . list ( ); /执行查询 , 获取数据观察运行期hib r ate生成的sql 语句: electtuser ida i ,tus r0 name sname, t ser0_.group_id as gr up_i , t se 0 . ser

6、_typeuser_ ype, tus 0_. ex asse om t_us r t s r0_ he e( tuser0 . ame eri )f updat 这里 hiberna 通过使用数据库的 orupd te 子句实现了悲观锁机制。h b rn e的加锁模式有 :2? lo kmo e.n ne : 无锁机制。?l ckmo e.wri e : hib rna 在 ins rt3和 upd te 记录的时候会自动获取? l ck od read : h be ate 在读取记录4的时候会自动获取。?以上这三种锁机制一般由 ib rnate 内部使用, 如 h b rnate5为了保

7、证up ate过程中对象不会被外界修改,会在s e 方法实现中自动为目标对象加上wri 锁。?7lockmod gra :利用数据库的 forupdate子句加锁。?l ck d .upgrade_now t : racle的特定实现, 利用 orac e 的 for upda te owait子句实现加锁。10 上面这两种锁机制是我们在应用层较为常用的,加锁一般通过以下方法实现:11 ? crit ia.se lockmode ? u r .setlockm de?1 s ss o . c 注意 ,只有在 开始之前(也就是h be at 生成sql之前) 定加 ,才会真正通 数据 的 机制

8、行加 理,否 ,数据已 通 不包含for pdate子句的sel ctsql 加 来,所 数据 加 也就无从 起。 了更好的理解se ct update的 表的 程, 本人将要以m s l 例 , 行相 的 解 ?开启两个 窗口,其中一个窗口 行命令:be in ;mysql2, 0row a c e (0. sec)q ery o3?4 pinfo f upda ;my ql select * from e5? - - -+ - +- - -+ - - -+-6 | fs l y |? - -+- +-| em no | empname | fa7 +-+ - -8 sdfs| nu|nu

9、l |?324234 | df| 12339? 1 1 |? - -+- - -+- +- - - | 110 0 sec)2 r s i set (0.11 个 候打开窗口b 行更新或插入操作:1 my q upda e emp nfose fa =12 wherefemp o= 23 ; 个 候窗口b 的更新或插入操作不会 行,会一直在等待,直到a 窗口的事 提交了: ysq co i ; ?query o ,0 r s affected(0.00 sec)2b 窗口的更新才开始 行。?那么 for update到底 定表 是行呢?由于 i nodb 是 w-levellock ,所以只有

10、明确的指定主 ,my ql 才会 行 row l ck ( 只 住被 取的 料例),否 m sql 将会 行tabl ck ( 将整个资料表单给锁住)。例 1 : (明确指定主键,并且有此笔资料,r w l k)se ect * ro produ ts wher id = 3for p a ; ?3 ?2? r m produ s e id =3 andtype = for upda ;select *例 2: (明确指定主键,若查无此笔资料,无 o k)se ct*fromp d ctsw erid =-1foupdate;例 :(无主键 ,tabl k)ele t romproduc s

11、w ername=mouseorupate;例 :(主键不明确,tab lock)se e t*fromp odu tswhe e d 3for u da e;例 5 : (主键不明确, table lo k)select *fr m pr ductswh re idlike3 f r up ate;注 :fr u d e 仅适用于 nnod ,且必须在交易区块(be n/ ommit) 中才能生效。 ?注 2: 要测试锁定的状况,可以利用m q的 m andmode,开二个视窗来做测试。在mysq 5.0 中测试确实是这样的另外:m只支持表级锁 ,innerdb支持行级锁添加了(行级锁/ 表

12、级锁)锁的数据不能被其它事务再锁定,也不被其它事务修改(修改、删除 ) 。是表级锁时 ,不管是否查询到记录 ,都会锁定表。到这里 ,悲观锁机制你应该了解一些了吧乐观锁相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言 ,这样的开销往往无法承受。如一个金融系统,当某个操作员读取用户的数据,并在读出的用户数据的基础上进行修改时 (如更改用户帐户余额),如果采用悲观锁机制 ,也就意味着整个操作过程中(从操作员读出数据、开始修改直至提交修改结果的全过程 ,甚至还包括操作员中途

13、去煮咖啡的时间) ,数据库记录始终处于加锁状态,可以想见 ,如果面对几 百上千个并发 ,这样的情况将导致怎样的后果。乐观锁机制在一定程度上解决了这个问题。乐观锁 ,大多是基于数据版本ver o )记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “ ve sion ” 字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对 ,如果提交的数据 版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。?假如数据库中账户余额为0 ,vers o

14、 为 ,操作员 a 读出余额 ,并修改为5 ,而在操作的同时操作员b 也读出了账户余额00 ,并修改为80, 完成了操作录入系统,vrsion从 1 加上变为 2,余额修改为 0,操作员 b 也提交了记录, v rsion也变为 2 ,余额则是 8,但是此时数据库发现,提交的ver ion 为 2,当前版本也是,不满足“ 提交版本必须大于记录当前版本才能执行更新“的乐观锁策略。因此,操作员 的提交被驳回。 这样,就避免了操作员b 用基于 ve sion 的旧数据修改的结果覆盖操作员 的操作结果的可能。从上面的例子可以看出,乐观锁机制避免了长事务中的数据库加锁开销(操作员a 和操作员 b 操作过

15、程中,都没有对数据库数据加锁),大大提升了大并发量下的系 统整体性能表现。需要注意的是 ,乐观锁机制往往基于系统中的数据存储逻辑,因此也具备一定的局限性,如在上例中,由于乐观锁机制是在我们的系统中实现,来自外部系统的用户余额更新操作不受我们系统的控制,因此可能会造成脏数据被更新到数据库中。在系统设计阶段,我们应该充分考虑到这些情况出现的可能性,并进行相应调整(如将乐观锁策略在数据库存储过程中实现,对外只开放基于此存储过程的数据更新途径 ,而不是将数据库表直接对外公开)。 er ate在其数据访问引擎中内置了乐观锁实现。如果不用考虑外部系统对数据库的更新操作,利用hiber at 提供的透明化乐

16、观锁实现,将大大提升我们的生产力。hibernate使用乐观锁我只说一下注解的方式:在 enti y 中加入以下代码p iva eintve io ;1? ver ion3 olumn (na e = vers n ,leng h =11 ) ?publ c i t g ver io4? 6?n() 7?8? 9?1retu n e s n;0?pub cvoid setve sion(in versio) ? hi versi n sion;这样就可以轻松实现hi e na e 乐观锁方式。常见并发同步案例分析?案例一 :订票系统案例 ?某航班只有一张机票,假定有 1w 个人打开你的网站来订

17、票,问你如何解决并发问题 (可扩展到任何高并发网站要考虑的并发读写问题)?问题 ,1w 个人来访问, 票没出去前要保证大家都能看到有票,不可能一个人在看到票的时候别人就不能看了。到底谁能抢到 ,那得看这个人的“运气”(网络快慢等 )其次考虑的问题,并发,1个人同时点击购买,到底谁能成交 ?总共只有一张票。?首先我们容易想到和并发相关的几个方案:?锁同步同步更多指的是应用程序的层面,多个线程进来 ,只能一个一个的访问,java 中指的是n riniz d 关键字。锁也有2 个层面 ,一个是 jaa 中谈到的对象锁, 用于线程同步; 另外一个层面是数据库的锁;如果是分布式的系统,显然只能利用数据库

18、端的锁来实现。假定我们采用了同步机制或者数据库物理锁机制,如何保证个人还能同时看到有票,显然会牺牲性能 ,在高并发网站中是不可取的。使用hib rna e 后我们提出了另外一个概念:乐观锁、悲观锁 (即传统的物理锁 );采用乐观锁即可解决此问题。乐观锁意思是不锁定表的情况下,利用业务的控制来解决并发问题 ,这样即保证数据的并发可读性又保证保存数据的排他性,保证性能的同时解决了并发带来的脏数据问题。 ?h b rnat 中如何实现乐观锁 :前提:在现有表当中增加一个冗余字段, er i n 版本号,ln 类型原理: 1?)只有当前版本号= 数据库表版本号,才能提交 ?)提交成功后,版本号 e s

19、 o +案例一: 案例二、 股票交易系统、 银行系统 ,大数据量你是如何考虑的?首先 ,股票交易系统的行情表 ,每几秒钟就有一个行情记录产生,一天下来就有 (假定行情3 秒一个 ) 股票数量 20 6 条记录 ,一月下来这个表记录数量多大? ra le 中一张表的记录数超过后 查询性能就很差了, 如何保证系统性能?再比如, 中国移动有上亿的用户量, 表如何设计?把所有用于存在于一个表么?所以 ,大数量的系统 ,必须考虑表拆分(表名字不一样,但是结构完全一样),通用的几种方式:(视情况而定)1 )按业务分,比如手机号的表,我们可以考虑13 开头的作为一个表,131 开头的另外一张表 以此类推2 )利用 ora le 的表拆分机制做分表3) 如果是交易系统,我们可以考虑按时间轴拆分,当日数据一个表,历史数据弄到其它表。这里历史数据的报表和查询不会影响当日交易。?此外 ,我们还得考虑缓存这里的缓存 ,指的不仅仅是hib rn te ,hi ern 本身提供了一级二级缓存。这里的缓存独立于应用,依然是内存的读取,假如我们能减少数据库频繁的访问,那对系统肯定大大有利的。比如一个电子商务系统

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论