猫宁i

趁着年轻,好好生活,用心折腾。


  • 首页

  • 标签

  • 分类

  • 归档

  • 关于

  • 书单

  • 搜索

Redis 深度探险(四):Redis 高可用性解决方案之哨兵与集群

发表于 2019-11-20 | 分类于 Redis | 阅读次数:
本文字数统计: 21k | 阅读时长 ≈ 19 分钟

前言

在开始本章的讲解之前,我们首先从宏观角度回顾一下 Redis 实现高可用相关的技术。它们包括:持久化、复制、哨兵和集群,在本系列的前篇文章介绍了持久化以及复制的原理以及实现。本文将对剩下的两种高可用技术哨兵、集群进行讲解,讲一讲它们是如何进一步提高系统的高可用性?

Redis 的主从复制模式下,一旦主节点由于故障不能提供服务,需要手动将从节点晋升为主节点,同时还要通知客户端更新主节点地址,这种故障处理方式从一定程度上是无法接受的。Redis 2.8 以后提供了 Redis Sentinel 哨兵机制来解决这个问题。

在 Redis 3.0 之前,使用哨兵(sentinel)机制来监控各个节点之间的状态。Redis Cluster 是 Redis 的分布式解决方案,在 3.0 版本正式推出,有效地解决了 Redis 在分布式方面的需求。当遇到单机内存、并发、流量等瓶颈时,可以采用 Cluster 架构方案达到负载均衡的目的。

阅读全文 »

大话数据结构(二):大白话布隆过滤器 Bloom Filter

发表于 2019-10-11 | 分类于 数据结构 | 阅读次数:
本文字数统计: 9.7k | 阅读时长 ≈ 9 分钟

前言

“一个网站有 20 亿 url 存在一个黑名单中,这个黑名单要怎么存?若此时随便输入一个 url,你如何快速判断该 url 是否在这个黑名单中?并且需在给定内存空间(比如:500M)内快速判断出。” 这是一道经常在面试中出现的算法题。

很多人脑海中首先想到的可能是 HashSet,因为 HashSet 的底层是采用 HashMap 实现的,理论上时间复杂度为:O(1)。达到了快速的目的,但是空间复杂度呢?URL 字符串通过 Hash 得到一个 Integer 的值,Integer 占 4 个字节,那 20 亿个 URL 理论上需要:4 字节 (byte) * 20 亿 = 80 亿 (byte) ≈ 7.45G 的内存空间,不满足空间复杂度的要求。

还有一种方法就是位图法[1],每个 URL 取整数哈希值,置于位图相应的位置上,看上去是可行的。但位图适合对海量的、取值分布很均匀的集合去重。位图法的所占空间随集合内最大元素的增大而增大,即空间复杂度随集合内最大元素增大而线性增大。要设计冲突率很低的哈希函数,势必要增加哈希值的取值范围,4G 的位图最大值是 320 亿左右,为 50 亿条 URL 设计冲突率很低、最大值为 320 亿的哈希函数比较困难。这就会带来一个问题,如果查找的元素数量少但其中某个元素的值很大,比如数字范围是 1 到 1000 亿,那消耗的空间不容乐观。因此,出于性能和内存占用的考虑,在这里使用布隆过滤器才是最好的解决方案:布隆过滤器是对位图的一种改进。

这里就引出本文要介绍的 “布隆过滤器”。

阅读全文 »

深入浅出集合框架(二):为并发而生的 ConcurrentHashMap

发表于 2019-09-27 | 分类于 集合 | 阅读次数:
本文字数统计: 27k | 阅读时长 ≈ 25 分钟

前言

ConcurrentHashMap 从 JDK 1.5 开始随 java.util.concurrent 包一起引入 JDK 中,主要为了解决 HashMap 线程不安全和 Hashtable 效率不高的问题。

HashMap 是我们日常开发中最常见的一种容器,根据键值对键的哈希值来确定值对键在集合中的存储位置,因此具有良好的存取和查找功能。但众所周知,它在高并发的情境下是线程不安全的。尤其是在 JDK 1.8 之前,rehash 的过程中采用头插法转移结点,高并发下,多个线程同时操作一条链表将直接导致闭链,易出现逆序且环形链表死循环问题,导致死循环并占满 CPU。JDK 1.8 以来,对 HashMap 的内部进行了很大的改进,采用数组 + 链表 + 红黑树的形式来进行数据的存储。rehash 的过程也进行了改动,基于复制的算法思想,不直接操作原链,而是定义了两条链表分别完成对原链的结点分离操作,在多线程的环境下,采用了尾插法,扩容后,新数组中的链表顺序依然与旧数组中的链表顺序保持一致,所有即使是多线程的情况下也是安全的。JDK 1.8 中的 HashMap 虽然不会导致死循环,但是因为 HashMap 多线程下内存不共享的问题,两个线程同时指向一个 hash 桶数组时,会导致数据覆盖的问题,所以 HashMap 是依旧是线程不安全的。

HashTable 是线程安全的容器,它在所有涉及到多线程的操作都加上了 synchronized 关键字来锁住整个 table,这就意味着所有的线程都在竞争一把锁,在多线程的环境下,它是安全的,但是无疑是效率低下的,因此 Hashtable 已经是 Java 中的遗留容器,已经不推荐使用。

因此在多线程条件下,需要满足线程安全,我们可使用 Collections.synchronizedMap 方法构造出一个同步的 Map,使 HashMap 具有线程安全的能力;或者直接使用线程安全的 ConcurrentHashMap。本篇文章将要介绍的 ConcurrentHashMap 是 HashMap 的并发版本,它是线程安全的,并且在高并发的情境下,性能优于 HashMap 很多。

阅读全文 »

Java8 那些事儿(五):函数式接口

发表于 2019-09-10 | 分类于 Java | 阅读次数:
本文字数统计: 10k | 阅读时长 ≈ 9 分钟

前言

函数式接口 (Functional Interface) 就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。函数式接口可以被隐式转换为 lambda 表达式。Java 允许利用 Lambda 表达式创建这些接口的实例。java.util.function 包是 Java 8 增加的一个新技术点 “函数式接口”,此包共有 43 个接口。别指望能够全部记住他们,但是如果能记住其中 6 个基础接口,必要时就可以推断出其余接口了。这些接口是为了使 Lamdba 函数表达式使用的更加简便,当然你也可以自己自定义接口来应用于 Lambda 函数表达式。

JDK 1.8 API 包含了很多内建的函数式接口,比如 Comparator 或者 Runnable 接口,这些接口都增加了 @FunctionalInterface 注解以便能用在 Lamdba 上。现如今,我们则从 Function 常用函数入口,真正了解一下函数式接口。

阅读全文 »

了不起的消息队列(一):浅谈消息队列及常见的分布式消息队列中间件

发表于 2019-08-30 | 分类于 消息队列 | 阅读次数:
本文字数统计: 9.2k | 阅读时长 ≈ 8 分钟

背景

分布式消息队列中间件是是大型分布式系统不可缺少的中间件,通过消息队列,应用程序可以在不知道彼此位置的情况下独立处理消息,或者在处理消息前不需要等待接收此消息。所以消息队列主要解决应用耦合、异步消息、流量削锋等问题,实现高性能、高可用、可伸缩和最终一致性架构。消息队列已经逐渐成为企业应用系统内部通信的核心手段,当前使用较多的消息队列有 RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMQ 等,而部分数据库如 Redis、MySQL 以及 PhxSQL 也可实现消息队列的功能。

在日常学习与开发过程中,消息队列作为系统不可缺少的中间件,显得十分的重要。在现代云架构中,应用程序被分解为多个规模较小且更易于开发、部署和维护的独立构建块。消息队列可为这些分布式应用程序提供通信和协调。而本人也在工作的过程中,前前后后后接触到了 Kafka、RabbitMQ 两款消息队列。所以,本系列文章也主要以 RabbitMQ 和 Kafka 两款典型的消息中间件来做分析。本文是该系列的开篇,主要讲解消息队列的概述、特点等,然后对消息队列使用场景进行分析,最后对市面上比较常见的消息队列产品进行技术对比。

阅读全文 »

Java 并发编程之美(六):J.U.C 之线程同步辅助工具类

发表于 2019-08-07 | 分类于 并发 | 阅读次数:
本文字数统计: 26k | 阅读时长 ≈ 24 分钟

前言

Java 并发编程是整个 Java 开发体系中最难以理解但也是最重要的知识点,也是各类开源分布式框架(如 ZooKeeper、Kafka、Spring Cloud、Netty 等)中各个并发组件实现的基础。J.U.C 并发包,即 java.util.concurrent 包,大大提高了并发性能,是 JDK 的核心工具包,是 JDK 1.5 之后,由 Doug Lea 实现并引入。而 AQS 被认为是 J.U.C 的核心。

AQS 是一个抽象类,并没有对并发类提供了一个统一的接口定义,而是由子类根据自身的情况实现相应的方法,AQS 中一般包含两个方法 acquire(int)、release(int),获取同步状态和释放同步状态,AQS 根据其状态是否独占分为独占模式和共享模式。

  • 独占模式:同一时刻最多只有一个线程获取同步状态,处于该模式下,其他线程试图获取该锁将无法获取成功。
  • 共享模式:同一时刻会有多个线程获取共享同步状态,处于该模式下,其他线程试图获取该锁可能会获取成功。

同步器根据同步状态分为独占模式和共享模式,独占模式包括类:ReentrantLock、ReentrantReadWriteLock.WriteLock,共享模式包括:Semaphore、CountDownLatch、ReentrantReadWriteLock.ReadLock,本文将着重介绍一下 java.util.concurrent 包下一些辅助同步器类:CountDownLatch、CyclicBarrier、Semaphore、Exchanger、Phaser。

阅读全文 »

MySQL 进阶讲解(二):快速生成测试数据以及 EXPLAIN 详解

发表于 2019-07-28 | 分类于 MySQL | 阅读次数:
本文字数统计: 15k | 阅读时长 ≈ 14 分钟

前言

索引类似大学图书馆建书目索引,可以提高数据检索的效率,降低数据库的 IO 成本。MySQL 在 300w 条记录左右性能开始逐渐下降,虽然官方文档说 500~800w 记录,所以大数据量建立索引是非常有必要的。MySQL 提供了 EXPLAIN,用于显示 SQL 执行的详细信息,可以进行索引的优化。使用 EXPLAIN 关键字可以模拟优化器执行 SQL 查询语句,从而知道 MySQL 是如何处理你的 SQL 语句的,分析你的查询语句或是表结构的性能瓶颈。 可以帮助选择更好的索引和写出更优化的查询语句。

本章首先介绍如何通过存储过程随机生成大量随机数据作为 EXPLIAN 的测试数据,然后通过例子详解 EXPLIAN 用法以及各字段含义,最后对 EXPLIAN 用途进行总结。

阅读全文 »

Redis 深度探险(三):Redis 单机环境搭建以及配置说明

发表于 2019-07-13 | 分类于 Redis | 阅读次数:
本文字数统计: 37k | 阅读时长 ≈ 33 分钟

前言

经过 Redis 深度探险系列的学习相信大家对 Redis 的数据结构、对象、持久化机制、过期键删除策略等知识有了大致的了解,本篇博文主要讲述 Redis 的安装步骤,然后介绍一下 Redis 配置说明,最后对 Redis 集群搭建进行详细的讲解。

阅读全文 »

Git 在团队中的最佳实践(二):如何正确使用 Git flow 工作流

发表于 2019-06-29 | 分类于 Git | 阅读次数:
本文字数统计: 9.8k | 阅读时长 ≈ 9 分钟

前言

当在团队开发中使用版本控制系统时,商定一个统一的工作流程是至关重要的。Git 的确可以在各个方面做很多事情,然而,如果在你的团队中还没有能形成一个特定有效的工作流程,那么混乱就将是不可避免的。基本上你可以定义一个完全适合你自己项目的工作流程,或者使用一个别人定义好的。就像代码需要代码规范一样,代码管理同样需要一个清晰的流程和规范。

Git flow 工作流是经典模型,体现了工作流的经验和精髓。随着项目过程复杂化,会感受到这个工作流中深思熟虑和威力!Git flow 工作流没有用超出功能分支工作流的概念和命令,而是为不同的分支分配一个很明确的角色,并定义分支之间如何和什么时候进行交互。在这章节中我们将一起学习一个当前非常流行的工作流 Git flow。

阅读全文 »

Java 并发编程之美(五):揭开 InheritableThreadLocal 的面纱

发表于 2019-06-03 | 分类于 并发 | 阅读次数:
本文字数统计: 14k | 阅读时长 ≈ 12 分钟

前言

博客《Java 并发编程之美(四):深入剖析 ThreadLocal》提到 ThreadLocal 变量的基本使用方式,ThreadLocal 是一个本地线程副本变量工具类,主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个线程依赖不同的变量值完成操作的场景。但是在实际的开发中,有这样的一种需求:父线程生成的变量需要传递到子线程中进行使用,那么在使用 ThreadLocal 似乎就解决不了这个问题。由于 ThreadLocal 设计之初就是为了绑定当前线程,如果希望当前线程的 ThreadLocal 能够被子线程使用,实现方式就会相当困难。在此背景下,InheritableThreadLocal 应运而生,使用 InheritableThreadLocal 这个变量就可以轻松的在子线程中依旧使用父线程中的本地变量。

阅读全文 »
123…5
猫宁i

猫宁i

趁着年轻,好好生活,用心折腾。
47 日志
16 分类
106 标签
RSS
Links
  • 我的镜像站
  • crossoverJie's Blog
  • Format's Notes
  • 渣博客
  • Sanarous
© 2017 – 2020 猫宁i | 博客全站字数: 655k
由 Hexo 强力驱动 v3.8.0
|
主题 – NexT.Muse v7.0.1
0%