20211128Java高并发核心编程卷1
Zookeeper 相关
Zookeeper 的核心优势是实现了分布式环境的一致性,简单地说:任何时刻我们访问 Zookeeper 的树结构时,不同的节点返回的数据是一致的。Zookeeper 保证了分布式环境下数据的一致性。
几种数据库错误:
“脏读” 是指一个事务中访问到另一个事务未提交的数据,也就是说还没有准备好就被访问了,这可能是半成品或者是错误的中间数据。
“不可重复读” 是指在一个事务内根据同一条件对数据进行多次查询,但是结果却不一致,原因是其他事务对该数据进行了修改。
“幻读” 是指两个完全相同的查询执行时,第二次查询所返回的结果集和第一次查询的不相同,原因是另外一个事务新增、删除了第一个事务结果集之中的数据,也就是我查出来了,但是这个结果集又被修改了。
相同点和不同点:
相同点都是读到错误的数据,只是错误产生的原因不一样。
不同点对于 “脏读” 来说,是取到了还没有准备好的数据。不可重复读是数据前后几次的源数源不一致。幻则是结果集又被别的事务操作了。
内核和进程缓存区
在应用程序中,无论是 Socket IO 还是 文件 IO ,都属于上层应用的开发,他们在输入(Input)/ 输出(Output)维度上的执行流程是类似的,都是内核缓冲区和进程缓存区之间进行数据交换。
内核和上层应用的数据交换,实际上是等待批量操作合并以提高效率,这里很大可能不是立刻写入的,对于 unix 相关的系统提供了 fsync 表示强制写入到磁盘。
IO 相关的模型
为了提高性能,操作系统引入了一种新的系统调用,专门用于查询 IO 文件描述符的就绪状态,在 Linux 中有 select / epoll 系统调用,通过这个系统调用可以监视多个文件描述符,一旦某个就绪,内核就把该状态传递给应用,然后应用根据对应的类型去操作。这个一种实现的可能就是轮询。
阻塞 IO 的优点:应用开发简单,阻塞等待期间,线程挂起不消耗 CPU 资源。
同步非阻塞 IO 的缺点是不断轮询内核,这会占用大量 CPU 时间,效率比较低。
IO多路复用
使用 IO 多路复用 的方法为,创建,监听,特定线程去轮询他们的状态。典型的,例如 epoll ,就是 epoll create / epoll ctrl / epoll wait 实际上 wait 是阻塞的,如果等待时间为 0 ,那么就是非阻塞的,对此我们可以轮询去查询这些 wait 的状态。这里可以去仿造 netty 或者 redis 去做,其中 netty 是使用 Java 现成的 selector 去做的, redis 则是直接基于 IO 多路复用的系统调用,例如 selelct 或者 epoll 等等。
IO 多路复用的优点是一个选择器查询线程可以同时处理多个网络连接,所以用户程序不需要创建大量的线程也不必维护线程,从而大大降低开销。
使用方式可以为拿着一组 fd 去不断的轮询,有数据了就去给到对应的用户,没有数据就再去轮询,至于轮询发现了数据的后续操作也可以给到一个专门的线程池去处理这些任务,以提高效率。