缓存击穿、缓存穿透与缓存雪崩
缓存是计算机系统中应用非常广泛的技术,最经典的,操作系统中处处是缓存,缓存可以大大提升数据访问速率。
在业务中,数据库(MySQL)面对大量的并发请求,会出现两个问题:
每次请求都需要查询数据库,速度很慢;
数据库无法承受如此大的请求流量,可能引起数据库宕机;
为解决这两个问题,一般会在内存中设置缓存,通常是使用Redis作为缓存,对于数据库的查询请求首先查询缓存,如果查不到,再去查询数据库。
引入缓存之后又会面临三个新的问题,即缓存击穿、缓存穿透以及缓存雪崩。
缓存击穿当缓存中没有某个数据,但是数据库中有这个数据时,对于数据的访问会直接访问数据库,于是——
一个热点key每时每刻都在接受大量的并发访问,当这个热点key的缓存过期时,大量的并发请求同时涌入到数据库中,导致后端数据库的压力陡然增大,引发缓存击穿。
概括来讲,就是由于缓存key过期,导致大量请求涌入后端数据库而造成数据库压力骤然增大。
如何解决缓存击穿?
既然缓存击穿是由于热点缓存key的过期导致的,那么一种方法是设置热点key永不过期。
使用分布式锁,当查询缓存未命中时,首先申请分 ...
Java反射机制
在Java中,所有对象都有两种类型,即编译时类型和运行时类型。
编译时类型是在程序代码编译解决确定的类型,而运行时类型是在程序运行时根据实际的对象类型确定的。
并且由于多态机制,很多时候一个对象的编译时类型和运行时类型并不是一致的。
譬如,对于如下代码:
Object i = new String("qwe");i.getClass();
对象i的编译时类型为Object,但是当我们使用getClass()获取它的所属类的Class类对象时,得到的结果却是java.lang.String
如果想要调用对象运行时类型的方法,那么就需要反射机制,因为在编译的时候,并不知道对象的运行时信息。
反射概述反射机制允许我们在运行时借助Reflection API获取到任何类的内部信息,并可以直接操作任何对象的属性和方法。
当类被JVM加载之后,会在方法区产生一个Class类型的对象,这个类包含了完整的类的结构信息。
反射机制就是基于每个类的唯一的Class对象实现的。
反射第一步——获得Class对象在反射操作的第一步,首先是要获得一个Cla ...
第一个Kubernetes应用
这两天搭建了一个Kubernetes集群,包含三个节点,如图所示:
接下来该学习如何在k8s集群上运行第一个k8s应用了。
准备镜像首先第一步,我们应该准备我们运行这个应用所需要的容器镜像。
编写应用配置文件有了容器镜像之后,我们需要编写应用配置文件告诉k8s我们想要如何运行我们的容器。
应用配置文件一般是YAML格式的,其中包含容器的定义、参数、配置等等信息,然后只需一条指令(kubectl create -f)就可以通过这个YAML文件把容器运行起来。
一个典型的YAML格式应用配置文件示例如下:
运行应用# 执行如下指令即可运行k8s应用kubectl create -f nginx-test.yaml# 通过如下指令查看应用的运行状态是否与预期一致# 这个指令从k8s中获取指定的API对象kubectl get pods -l app=nginx
可以看到两个nginx镜像已经运行起来了!
我们甚至没有手动拉取镜像,因为在使用kubectl create指令时,k8s会自动将所需镜像拉取下来。
很简单,不是吗?可以看到运行k8 ...
浅谈Kubernetes
Kubernetes,简称k8s,是云原生生态的基石,是CNCF技术栈的核心。
注: CNCF即为云原生计算基金会,是一个开源的软件基金会,致力于云原生技术的普及及可持续发展。许多有名的项目都托管在这个社区当中,包括Docker、Kubernetes。
Kubernetes脱骨于Google的Borg系统,而Borg承载了Google公司整个基础设施的核心依赖,k8s在Borg体系的指导之下,在众多容器编排工具中脱颖而出。
为什么需要容器编排一个Docker容器本质上是一个进程,当然处理不了太多的事情,在一个大型项目当中,可能会有成千上万个容器共同工作,如何处理容器之间复杂的关系让它们协同起来,是一个很棘手的问题。
于是类似于k8s这样的容器编排工具就应运而生。
用户的期望作为用户,我们已经有了应用的容器镜像,我们希望k8s这样的工具,给我们: 在一个给定的集群上运行这个应用,并且提供路由网关、水平扩展、监控、备份、灾难恢复等一系列运维能力。
Kubernetes架构
图源自[1],展现了Kubernetes的全局架构。
k8s由Master和Node两种节 ...
分布式系统概述
引言当只有一台计算机的时候,也就是单机系统,我们不需要考虑通信、容错、一致性等等问题,只需要将应用部署在这台计算机上,它的正确运行是显而易见的——就像我们平时所做的那样,自己编写一个C++程序并运行。
但是单机系统的弊端也是很明显的——它的资源很有限。它的硬盘、CPU、内存都是有限的,当我们的应用需要更多的资源时,一台计算机难以支撑它的运行。
一个很直观的想法是:增加更多的计算机,这样我们就有更多资源了!
这就是分布式系统: 很多台计算机组成一个系统,协作运行大型的应用。
但是一个问题随之而来,那就是,在系统中增加了计算机之后,整个系统的性能也是随之增加的吗?可用性不随着系统的扩展而变化吗?未必。因为引入更多台计算机使得系统复杂度提升,就会带来额外的开销,影响整个系统的性能;而系统中的计算机可能会出现故障而导致整个系统不可用。
这就引出了分布式系统的目标: 可扩展性(Scalability)。
可扩展性(Scalability)
可扩展性是系统、网络或进程以一种有能力的方式处理不断增长的工作量的能力,或者是其扩大以适应这种增长的能力。
可扩展系统是指随着规模的 ...
解决方法The following signatures couldn't be verified because the public key is not available
概述今天在Ubuntu20.04上执行sudo apt-get update命令时,遇到以下错误:
Err:2 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial InRelease The following signatures couldn't be verified because the public key is not available: NO_PUBKEY B53DC80D13EDEF05
他说这个签名不能被验证,因为没有可用的公钥,并且表示没有B53DC80D13EDEF05这个密钥
解决方法我们给他加上这个密钥就可以了,使用命令:
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys B53DC80D13EDEF05
apt-key命令用于管理Debian Linux系统中的软件包密钥,每个发布的Debian软件包都是通过密钥认证的。adv: 告知apt-key工具使用高级模式–keyserver keyserver ...
解决方法-The connection to the server localhost:8080 was refused - did you specify the right host or port?
概述k8s集群在节点运行kubectl命令时出现错误:The connection to the server localhost:8080 was refused - did you specify the right host or port?出现这个问题的原因是kubectl命令需要使用kubernetes-admin来运行
解决方法依次进行下述步骤:
首先将主节点中的/etc/kubernetes/admin.conf文件拷贝到从节点相同的目录下
配置环境变量echo export KUBECONFIG=/etc/kubernetes/admin.conf >> ~/.bash_profile(这句要手打,不要复制粘贴,尤其是>>,否则会出错)
使环境变量生效source ~/.bash_profile
解决方法-It seems like the kubelet isn't running or healthy.
概述如果在使用kubeadm初始化(kubeadm init)或者添加节点到k8s集群(kubeadm join)中时,遇到类似下图的错误:只要出现了It seems like the kubelet isn’t running or healthy. 这句提示,都可以尝试使用下面的解决方法来解决。
解决方法依次执行:
sudo swapoff -asudo sed -i '/ swap / s/^/#/' /etc/fstab
即可。
Innovative Technology for CPU Based Attestation and Sealing论文翻译
Innovative Technology for CPU Based Attestation and Sealing是Intel SGX技术的官方论文,本文将翻译这篇文章。SGX技术提供了enclave环境,当今比较火的机密计算技术一般就是基于SGX技术来实现,当然也有其他的可以提供enclave环境的技术,例如TrustZone等,但是SGX应用更多,且相比之下更安全些。
本文中形似(注:···)的批注是我的批注,而非原文
Innovative Technology for CPU Based Attestation and Sealing(基于CPU的认证与密封新技术)AbstractIntel正在开发Intel®Software Guard Extensions(Intel®SGX)技术,这是Intel®架构的扩展,用于生成受保护的软件容器。容器被称为飞地。在飞地内部,软件的代码、数据和堆栈受到硬件强制访问控制策略的保护,这些策略可以防止对飞地内容的攻击。在一个软件和服务通过互联网部署的时代(注:也就是云计算时代),关键是能够通过有线或空中安全地远程提供飞地,有把握地知道机 ...
Rust安装与入门
由于站主的研究方向是内存安全,一些涉及到底层的开发会用到Rust,所以浅浅入门一下。
Rust安装Linux下Rust的安装只需要执行一条指令即可:
curl https://sh.rustup.rs -sSf | sh
由于网络问题,执行失败的话,多执行几次总会成功。安装选项选Proceed with installation (default)即可。
执行如下命令验证Rust安装是否成功:
rustc --version# 如果输出了版本,则表明安装成功!
Hello World!文件命名Rust程序的文件后缀名为.rs文件的命名规范为下划线连接的单词,例如hello_world.rs
编译与运行
编译: rustc main.rs
运行: Linux下:./main
fn main(){ println!("Hello World!");}
注:rustc只适合简单的Rust程序,如果Rust程序文件比较多,应该用Cargo来编译。
CargoCargo是Rust的构建系统和包管理工具。它的 ...