MySql
Redis
Hibernate
Zookeeper
Kafka
Apache Camel
MySql
关系型数据库
一、常用引擎
1.InnoDB引擎:提供了对数据库ACID事务的支持,并且还提供了行级锁和外键的约束,它的设计目标就是处理大数据容量的数据库系统;MySQL运行的时候,InnoDB会在内存中建立缓冲池,用于缓冲数据和索引;不支持全文搜索,启动也比较慢,不保存表的行数,所以当进行select count(*) from table指令的时候,需要进行全表扫描;由于锁的粒度小,写操作不会锁定全表,在并发度较高的场景下使用会提升效率。
2.MyIASM引擎:MySQL的默认引擎,不提供事务的支持,也不支持行级锁和外键;当执行插入和更新语句即执行写操作的时候需要锁定这个表,导致效率降低;保存了表的行数;如果表的读操作远远多于写操作,并且不需要事务支持的,可以首选MyIASM。
二、锁
行锁:InnoDB支持,默认行锁,开销大,加锁慢,会出现死锁,锁粒度小,发生锁冲突的概率小,并发度高;
表锁:MyISAM和InnoDB均支持,开销小,加锁快,不会出现死锁,锁定粒度大,发生锁冲突的概率高,并发量低;
乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下在此期间有没有别人去更新这个数据;数据库的乐观锁需要自己实现,如在表里面添加一个version字段,每次修改成功值加1,这样每次修改的时候先对比一下,自己拥有的version和数据库现在的version是否一致,如果不一致就不修改,这样就实现了乐观锁;
悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻止,直到这个锁被释放。
三、三范式
第一范式:强调的是列的原子性,即数据库表的每一列都是不可分割的原子数据项;
第二范式:要求实体的属性完全依赖于主关键字,所谓完全依赖是指不能存在仅依赖主关键字一部分的属性;
第三范式:任何非主属性不依赖于其它非主属性。
四、性能优化
为搜索字段创建索引(实现高效查找数据,B+树);避免使用select *,列出需要查询的字段;选择正确的存储引擎。
Redis
Key-Value数据库
功能:主从架构、数据缓存、分布式锁、支持数据持久化、支持事务、支持消息队列。
一、主从架构
读写分离,Master节点负责处理写请求,Slave节点只处理读请求;
主从同步,Master节点接收到写请求并处理后,需要告知Slave节点数据发生了改变,保持主从节点数据一致。
二、缓存
合理设置缓存的过期时间;
新增、更改、删除数据库操作时同步更新Redis,可以使用事务机制来保证数据的一致性;
缓存穿透:指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透;如果一个查询返回的数据为空,就把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。
三、Redis分布式锁
分布式锁:多进程的情况下,需要分布式锁;常用的分布式锁有三种,分别是基于数据库/redis/zookeeper。
Redis分布式锁其实就是在系统里面占一个坑,其他程序也要占坑的时候,占用成功了就可以继续执行,失败了就只能放弃或稍后重试。
占坑一般使用setnx指令,只允许被一个程序占有,使用完调用del释放锁;
Redisson框架,lua脚本,保证原子性;
缺陷:主从异步复制可能导致多个客户端同时完成加锁。
四、持久化
RDB:指定的时间间隔对数据进行快照存储;
AOF:每一个收到的写命令都通过write函数追加到文件中。
Hibernate
一、ORM框架
对象-关系映射,面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统;对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据;内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系;因此,ORM一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。
二、特性
1.对JDBC(java数据库连接)访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码;
2.Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现,很大程度的简化DAO层的编码工作;
3.Hibernate使用Java反射机制,而不是字节码增强程序来实现透明性;
4.映射的灵活性很出色,支持各种关系数据库,从一对一到多对多的各种复杂关系。
三、工作流程
1.通过Configuration config = new Configuration().configure();读取并解析hibernate.cfg.xml配置文件;
2.由hibernate.cfg.xml中的<mapping resource="com/xx/User.hbm.xml"/>读取并解析映射信息;
3.通过SessionFactory sf = config.buildSessionFactory();创建SessionFactory
4.Session session = sf.openSession();打开Sesssion
5.Transaction tx = session.beginTransaction();创建并启动事务
6.persistent operate操作数据,持久化操作
7.tx.commit();提交事务
8.关闭Session
9.关闭SesstionFactory
四、查询方式
1.HQL:面向对象的写法:
Query query = session.createQuery("from Customer where name = ?");
query.setParameter(0, "苍老师");
Query.list();
2.QBC:条件查询
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.eq("name", "花姐"));
List<Customer> list = criteria.list();
3.SQL:
SQLQuery query = session.createSQLQuery("select * from customer");
query.addEntity(Customer.class);
List<Customer> list = query.list();
五、缓存机制
分为一级缓存和二级缓存。
一级缓存就是Session级别的缓存,在事务范围内有效,内置的不能被卸载;二级缓存是SesionFactory级别的缓存,从应用启动到应用结束有效,是可选的,默认没有二级缓存,需要手动开启。
Hibernate的二级缓存默认是不支持分布式缓存的。
Zookeeper
Zookeeper是一个开放源码的分布式应用程序协调服务,为分布式应用提供一致性服务的软件。
一、功能
1.集群管理:监控节点存活状态、运行请求等;
2.主节点选举:主节点挂掉了之后可以从备用的节点开始新一轮选主,主节点选举说的就是这个选举的过程,使用zookeeper可以协助完成这个过程;
3.分布式锁:zookeeper提供两种锁:独占锁、共享锁。独占锁即一次只能有一个线程使用资源,共享锁是读锁共享,读写互斥;
4.命名服务:在分布式系统中,通过使用命名服务,客户端应用能够根据指定名字来获取资源或服务的地址等信息。
二、部署模式
单机部署:一台集群上运行;
集群部署:多台集群运行;
伪集群部署:一台集群启动多个 zookeeper实例运行。
三、主从节点的状态同步
Zookeeper的核心是原子广播,这个机制保证了各个server之间的同步,实现这个机制的协议叫做zab协议,zab协议有两种模式,分别是恢复模式(选主)和广播模式(同步);当服务启动或者在领导者崩溃后,zab就进入了恢复模式,当领导者被选举出来,且大多数server完成了和leader的状态同步以后,恢复模式就结束了,状态同步保证了leader和server具有相同的系统状态。
Kafka
Kafka是一个分布式、支持分区的、多副本的,基于zookeeper协调的分布式消息系统。
一、特性
高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒;
可扩展性:kafka集群支持热扩展;
持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失;
容错性:允许集群中节点失败;
高并发:支持数千个客户端同时读写。
二、使用场景
1.日志收集:一个公司可以用Kafka收集各种服务的log,通过kafka以统一接口服务的方式开放给各种consumer,例如hadoop、Hbase、Solr等;
2.消息系统:解耦和生产者和消费者、缓存消息等。
3.用户活动跟踪:Kafka经常被用来记录web用户或者app用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,然后订阅者通过订阅这些topic来做实时的监控分析,或者装载到hadoop、数据仓库中做离线分析和挖掘;
4.运营指标:Kafka也经常用来记录运营监控数据,包括收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告。
Apache Camel
一、Camel
Camel框架的核心是一个路由引擎,或者更确切地说是一个路由引擎构建器。它允许定义自己的路由规则,决定从哪个源接收消息,并决定如何处理这些消息并将其发送到其他目标。
Camel提供更高层次的抽象,使用户可以使用相同的API与各种系统进行交互,而不管系统使用的协议或数据类型如何,Camel中的组件提供了针对不同协议和数据类型的API的特定实现,开箱即用,Camel支持80多种协议和数据类型。
1.CamelContext
2.Routes
通过路由可以实现:客户端与服务端,生产者与消费者的解耦
//从ftp服务上获取订单信息,将其发送到JMS队列
//from可以理解成消费者:表示从ftp服务上获取数据进行消费
from("ftp://rider.com/orders?username=rider&password=secret")
//to可以理解成生产者:表示将数据发送给jms
.to("jms:incomingOrders");
3.endpoint URI
Scheme:指明使用的是FtpComponent,Context path:ftp服务和端口号,以及文件路径,Options:一些操作配置,每个组件都不同
4.Exchange
二、编码格式
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.15.6</version>
</dependency>
public class FileCopierWithCamel {
public static void main(String args[]) throws Exception {
// create CamelContext
CamelContext context = new DefaultCamelContext();
// add our route to the CamelContext
context.addRoutes(new RouteBuilder() {
public void configure() {
from("quartz://report?cron=0+0+6+*+*+?")
.to("http://riders.com/orders/cmd=received&date=yesterday")
.process(new OrderToCsvProcessor())
.to("file://riders/orders?fileName=report-${header.Date}.csv");
}
});
// start the route and let it do its work
context.start();
Thread.sleep(10000);
// stop the CamelContext
context.stop();
}
}
public class OrderToCsvProcessor implements Processor {
public void process(Exchange exchange) throws Exception {
String custom = exchange.getIn().getBody(String.class);
String id = custom.substring(0, 9);
String customerId = custom.substring(10, 19);
String date = custom.substring(20, 29);
String items = custom.substring(30);
String[] itemIds = items.split("@");
StringBuilder csv = new StringBuilder();
csv.append(id.trim());
csv.append(",").append(date.trim());
csv.append(",").append(customerId.trim());
for (String item : itemIds) {
csv.append(",").append(item.trim());
}
exchange.getIn().setBody(csv.toString());
}
}