前言Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率。本文旨在对锁相关源码(本文中的源码来自JDK 8和Netty 3.10.6)、使用场景进行举例,为读者介绍主流锁的知识点,以及不同的锁的适用场景。
Java中往往是按照是否含有某一特性来定义锁,我们通过特性将锁进行分组归类,再使用对比的方式进行介绍,帮助大家更快捷的理解相关知识。下面给出本文内容的总体分类目录:
1. 乐观锁 VS 悲观锁乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角度。在Java和数据库中都有此概念对应的实际应用。
先说概念。对于同一个数据的并发操作,悲观锁认为自己在使用数据的时候一定有别的线程来修改数据,因此在获取数据的时候会先加锁,确保数据不会被别的线程修改。Java中,synchronized关键字和Lock的实现类都是悲观锁。
而乐观锁认为自己在使用数据时不会有别的线程修改数据,所以不会添加锁,只是在更新数据的时候去判断之前有没有别的线程更新了这个数据。如果这个数据没有被更新,当前线程将自己修改的数据成功写入。如果数据已经被其他线程更新,则根据不同的实现 ...
MapDB****特性
mapdb是一个内嵌的纯java的数据库,提供了并发的HashMap、TreeMap、Queue,可以基于堆外或者磁盘来存储数据。用户可以通过配置选择不同的机制来提高性能,比如可以配置多种不同的cache来减少反序列化的开销,提高读取性能;可以开启异步写引擎,使用后台线程来进行序列化和存储更新,来提高插入性能,减少rt。它支持ACID事务、MVCC隔离。它的代码精简,只有一个jar包,无其他依赖,总共才200kb。并且高度模块化,用户可以很容易的扩展,添加新特性。
MapDB****架构
从下面的类图,可以看出MapDB的整体脉络,它采用分层的设计,针对接口编程。上层只依赖下层的接口,具体实现可替换。顶层是针对用户的接口,也就是各种数据结构的接口。中间层是存储引擎Engine, 提供简单的key value接口,是MapDB的核心模块,管理对象为记录,通过记录id操作,用户不能直接使用。底层的是Volume,是对原始存储媒介的抽象,MapDB提供堆内、堆外、磁盘等存储媒介。这样的分层设计,使得MapDB的模块清晰,每一层都可以很容易的扩展,只需要实现接口即可。
...
MySQL和Lucene都可以对数据构建索引并通过索引查询数据,一个是关系型数据库,一个是构建搜索引擎(Solr、ElasticSearch)的核心类库。两者的索引(index)有什么区别呢?以前写过一篇《Solr与MySQL查询性能对比》,只是简单的对比了下查询性能,对于内部原理却没有解释,本文简单分析下两者的索引区别。
MySQL索引实现
在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的,本文主要讨论MyISAM和InnoDB两个存储引擎的B+Tree索引实现方式(HASH索引不能使用范围查询,只支持等值比较查询,不在此文章讨论)。
MyISAM索引实现
MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。下图是MyISAM索引的原理图:
图1是一个MyISAM表的主索引(Primary key)示意。可以看出MyISAM的索引文件仅仅保存数据记录的地址。在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。B+Tree的所 ...
TCP粘包/拆包TCP是个流协议,所谓流,就是没有界限的一串数据。大家可以想想河流里的流水,它们是连成一片的,其间并没有分界线。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP的拆包和粘包问题。
TCP粘包和拆包发生的原因问题产生的原因主要有三个,分别如下:
应用程序write写入的字节大小大于套接字发送缓冲区大小
进行MSS大小的TCP分段
以太网帧payload大于MTU进行IP分片
粘包问题的解决策略由于底层的TCP无法理解上层的业务数据,所以在底层是无法保证数据包不被拆分和重组的,这个问题只能通过上层的应用层协议栈设计来解决,根据业界的主流协议的解决方案,可以归纳如下:
消息定长,例如每个报文的大小为固定长度200字节,如果不够,空位补空格;
在包尾增加回车换行符进行分割,例如FTP协议;
将消息分为消息头和消息体,消息头中包含表示消息总长度(或者消息体长度)的字段,通常设计思路为消息头的第一个 ...
简介: [Sentinel](https://github.com/alibaba/Sentinel) 是阿里中间件团队研发的面向分布式服务架构的轻量级高可用流量控制组件,最近正式开源。Sentinel 主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助用户保护服务的稳定性。大家可能会问:Sentinel 和之前常用的熔断降级库 Netflix Hystrix 有什么异同呢?本文将从多
Sentinel 是阿里中间件团队研发的面向分布式服务架构的轻量级高可用流量控制组件,最近正式开源。Sentinel 主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助用户保护服务的稳定性。大家可能会问:Sentinel 和之前常用的熔断降级库 Netflix Hystrix 有什么异同呢?本文将从多个角度对 Sentinel 和 Hystrix 进行对比,帮助大家进行技术选型。
Overview先来看一下 Hystrix 的官方介绍:
Hystrix is a library that helps you control the interactions be ...
系统架构
未读订单单表早就已经突破两百G,由于查询维度较多,即使加了两个从库,优化索引,仍然存在很多查询不理想的情况。去年大量抢购活动的开展,使数据库达到瓶颈,应用只能通过限速、异步队列等对其进行保护;业务需求层出不穷,原有的订单模型很难满足业务需求,但是基于原订单表的DDL又非常吃力,无法达到业务要求。随着这些问题越来越突出,订单数据库的切分就愈发急迫了。
这次切分,我们的目标是未来十年内不需要担心订单容量的问题。
先对订单库进行垂直切分,将原有的订单库分为基础订单库、订单流程库等,本文就不展开讲了。
垂直切分
垂直切分缓解了原来单集群的压力,但是在抢购时依然捉襟见肘。原有的订单模型已经无法满足业务需求,于是我们设计了一套新的统一订单模型,为同时满足C端用户、B端商户、客服、运营等的需求,我们分别通过用户ID和商户ID进行切分,并通过PUMA(我们内部开发的MySQL binlog实时解析服务)同步到一个运营库。
水平切分
切分策略1. 查询切分将ID和库的Mapping关系记录在一个单独的库中。
查询切分
优点:ID和库的Mapping算法可以随意更改。缺点:引入额外的单点。
2. 范围切分比如 ...
我就是很多人里的那个嘴里说着不要二胎,却生了二胎的人。
之前我们同事说,很想生老二,我很决绝的说了我肯定不生,养不起养不起。后来疫情,我悄么声的怀了老二,等回到工作岗位,就有6个月了。我同事说,你这咋怀了,当时不是不要老二吗,反而我这说要生老二的,后来说服了自己,决定只生一个。
其实,不管你信不信,有些事情不能说的特别死,就像你说我从来不感冒,没想到过了几天感冒了一样。生活就是这么戏剧,活活把自己演成了小丑。
之前我确实是不想也不敢生二胎。观念转变是因为,看到老大,这个有着你遗传基因的小人儿,一点点长成了让你惊喜的样子。就很好奇,如果再有一个和自己有着血缘关系的男孩子(老大女孩),会是什么样,参与孩子成长的过程总是让人屡试不爽。
再者,老大那会也特别想要一个哥哥或姐姐。我说那是不能够了,生也只能是你的弟弟或妹妹。试想,一个不到4岁的孩子,会缠着你说,妈妈,咱们聊了天吧,聊聊生个孩子。我问她,为什么想要妈妈生个孩子。尽管这样问,其实我知道她回答不上来,毕竟才3岁多。于是我就引导着问她,是不是班里的小朋友都有兄弟姐妹(中途给她解释了一下什么叫做兄弟姐妹)啊?她说嗯,你看方方圆圆(她们班里的 ...
对象结构在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。下图是普通对象实例与数组对象实例的数据结构:
1 对象头HotSpot虚拟机的对象头包括两部分信息:
markword 第一部分markword,用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据的长度****在32位和64位的虚拟机(未开启压缩指针)中分别为32bit和64bit,官方称它为“MarkWord”。
klass 对象头的另外一部分是klass类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例. 32位4字节,64位开启指针压缩或最大堆内存<32g时 4字节,否则8字节
数组长度(只有数组对象有) 4字节如果对象是一个数组, 那在对象头中还必须有一块数据用于记录数组长度.int最大值2g,2^31,java数组(包含字符串)最长2g
2 实例数据实例数据部分是对象真正存储的有 ...
说明移动场景下DNS解析开销是整个网络请求中不可忽略的一部分。在弱网环境下,基于UDP的LocalDNS解析非常容易出现解析超时的问题,并且即使解析成功会消耗数百毫秒乃至更甚,对我们整个业务请求而言是非常不利的,它直接影响了客户的体验。
对于一个比较大众的应用而言,DNS的优化对整个应用的网络优化所占的权重是很大的。我们接下来从以下几个方面全面理解DNS,相信对我们开发中的网络优化会有不小的帮助。
DNS
认识DNS
DNS解析相关概念
DNS域名层次结构
权威DNS
递归DNS
公共DNS
转发DNS
域名解析记录方式
域名解析过程
全局负载均衡GSLB
智能DNS
DNS解析存在的问题
DNS劫持
DNS解析域名时缓存解析结果
转发解析
HTTPDNS
什么是HTTPDNS
HTTPDNS的特性
如何支持HTTPS
问题
主机是如何知道DNS服务器地的IP地址的?
为什么DNS采用UDP协议 ?
1. DNS1.1 认识DNSDNS(Domain Name System)是域名“系统”的英文缩写,是一种组织成域层次结构的计算机和网络服务命名系统,它用于T ...
前言我们在上一章节中介绍过数据库的带你了解数据库中事务的ACID特性 的相关用法。本章节主要来介绍下数据库中一个非常重要的知识点事务的隔离级别。如有错误还请大家及时指出~
问题:
事务的隔离级别有哪些?
如果并发事务没有进行隔离,会出现什么问题?
以下都是采用mysql数据库
在多个事务并发做数据库操作的时候,如果没有有效的避免机制,就会出现种种问题。大体上有以下问题:
一、引发的问题在并发事务没有进行隔离的情况下,会发生如下问题。
问题一:脏读脏读指一个事务读取了另外一个事务未提交的数据。
具体看后文案例介绍
问题二:不可重复读不可重复读指在一个事务内读取表中的某一行数据,多次读取结果不同。 不可重复读和脏读的区别是,脏读是读取前一事务未提交的脏数据,不可重复读是重新读取了前一事务已提交的数据。
具体看后文案例介绍
问题三:幻读(虚读)幻读(虚读)指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。
具体看后文案例介绍
二、概念2.1 事务的隔离级别分为:
Read uncommitted(读未提交)
Read Committed(读已提交)
Repeatable ...
