kafka rebalance

kafka rebalance Kafka session.timeout.ms heartbeat.interval.ms 参数的区别以及对数据存储的一些思考 在计算机世界中经常需要与数据打交道,这也是我们戏称 CURD 工程师的原因之一。写了两年代码,接触了不少存储系统,Redis、MySQL、Kafka、Elasticsearch 慢慢地发现背后的一些公共的设计思想总是那么似曾相识,再深究一下,就会发现一些隐藏在这些系统背后的数学理论。 生活中产生的大量数据需要交由计算机来处理,根据处理方式的不同分为 OLTP 和 OLAP 两大类应用。有些数据比如登录流水、系统日志信息,源源不断, 先采集下来抛给消息中间件(Kafka);有些数据,比如一条描述用户特征的记录,就适合存储到 MySQL,并按日期建查询索引。也就是说:面对大量的数据, 把数据存储起来只是一小步,重要的是如何把这些数据用起来,体现到存储系统则是:有没有一套方便的查询接口能够方便快速地查到我们想要的数据。 如果将数据放到 Kafka上了,那要怎么查?如果把数据放到 MySQL 上了,非常适合针对高 cardinality 列建 B+ 树索引查询,而对于文本类的数据,放到 ES 上, 则基于倒排索引这种数据结构,根据 tf-idf、bm25 等这些衡量文档相似度的算法来快速地获得想要的数据。 从这也可以看出,不同的存储系统,为了满足"查询",它们背后的存储原理(所采用的数据结构)是不同的。而对于这些存储系统而言,都面临着两个问题: 高可靠性和高可用性。可靠性,在我看来,是站在存储系统本身来看,一般是讨论单个实例如何保证数据的可靠。 比如,一个正在运行的MySQL实例,它根据checkpoint机制,通过redo log 文件来保证持久性,另外还有double write buffer,保证数据页的写入是可靠的。 类似地,在 Elasticsearch 里面也有 translog 机制,用来保证数据的可靠性。所以,想深入了解存储系统,不妨对比一下它们之间的各种 checkpoint 机制。 数据为什么需要有可靠性呢?根本原因还是内存是一种易失性存储,根据冯偌依曼体系结构,程序总是从内存中取数据交给CPU做运算。如果数据没有fsync到磁盘, 如果系统宕机那数据会不会丢? 而对于可用性,是从Client角度而言的。即我不管你背后是一个redis实例还是一个redis 集群,你只管正常地给我提供好读写服务就好了。这里为了避免SPOF, 分布式集群就派上用场了,一台机器挂了,另一台机器顶上。在分布式系统中,需要管理好各个存储实例,这时就需要节点的角色划分,比如master节点、controller节点之类的称呼。 毕竟管理是要有层级的嘛,大家角色都一样,怎么管理呢?在这一点上,Redis集群与Kafka集群或者Elasticsearch集群有很大的不同, 具体体现在Redis本质上是一个P2P结构的集群,而Elasticsearch和Kafka 采用的主从模型,为什么这么说呢?Redis虽然也有Master节点和Slave节点之分, 但它的各个Master节点之间是平等的,Redis的数据分布方式是hash16384个槽到各个master节点上,每个master节点负责处理落在这些槽内的数据, 这是从数据分布的角度来定义的Master节点,而Kafka中的Controller节点、Elasticsearch中的master节点并不是从数据分布的角度定义的,而是从集群元信息维护、 集群管理的角度定义的,关于它们之间的具体区别我在这篇文章中也有过一些描述。另外,MySQL作为关系型数据库,受数据完整性约束、事务支持的限制,在分布式集群能力上要弱一些。 最近碰到一个问题,多个业务往向一个 Kafka topic 发送消息,有些业务的消费量很大,有些业务的消息量很小。因 Kafka 尚未较好地支持按优先级来消费消息, 导致某些业务的消息消费延时的问题。一种简单的解决方案是再增加几个Topic,面对一些系统遗留问题,增加Topic带来的是生产者和消费者处理逻辑复杂性。 一种方法是使用Kafka Standalone consumer,先使用 consumer.partitionFor(“TOPIC_NAME”) 获取 topic 下的所有分区信息, 再使用consumer.assign(partitions)显示地为consumer指定消费分区。另一种方法是基于 consumer group 自定义 Kafka consumer 的分区分配策略, 那这时候就得对Kafka目前已有的分区分配策略有所了解,并且明白什么时候、什么场景下触发 rebalance? ...

2020-01-28 · 3 min · 450 words · -

pixel2, pixel3 root, android root

pixel2,pixel3 root, android root 线刷 android 安卓线刷升级 flash factory image for android device http://blog.wiloon.com/android/factory-image Enable USB Debugging mode Download MagiskManager apk 并安装 到手机 https://github.com/topjohnwu/Magisk 从第一步线刷升级用的镜像文件 image-blueline-sp1a.210812.016.c2.zip 里解压出 boot.img, 传到手机上的 download 目录 打开magisk mamanger, 点击 “未安装 Magisk” 后面的安装按钮, 在弹出的菜单中选择 “选择并修补一个文件 “, 然后 选择boot.img。 把打好补丁的boot.img传到电脑上 , 打补丁之后的boot.img的名字 应该 是magisk_patched.img 执行 adb reboot bootloader,到bootloader 刷入打好补丁的 boot.img fastboot flash boot patched_boot.img fastboot reboot 重启后系统已经root成功了。 https://blog.csdn.net/Ender_Zhao/article/details/108615512 https://www.teamandroid.com/2019/03/17/root-android-q-beta-google-pixel-2-pixel/embed/#?secret=dymLQPYWmm android root pixel Download Magisk Root https://github.com/topjohnwu/Magisk Download the TWRP Recovery ...

2020-01-26 · 1 min · 117 words · -

buildah

buildah # removes all dangling images, same as docker prune podman image prune # remove image buildah rmi 0d2d0133941b sudo pacman -S fuse-overlayfs sudo pacman -S buildah # login buildah login container.wiloon.com buildah login --tls-verify=false container.wiloon.com # buildah needs to run as root!!! # list all the images buildah images # build ### buildah bud -f Dockerfile -t <tag0> . buildah bud -f Dockerfile -t fedora-httpd . buildah push registry.wiloon.com/pingd-proxy:v0.0.1 # list all containers buildah containers buildah run <container name> buildah run $container -- dnf -y install java buildah rm $newcontainer buildah push fedora-bashecho docker-daemon:fedora-bashecho:latest container0=$(buildah from timer0) buildah run $container0 http: server gave HTTP response to HTTPS client https://github.com/containers/buildah/issues/4788 ...

2020-01-20 · 1 min · 114 words · -

linux capability, setcap/getcap

linux capability, setcap/getcap http://www.cnblogs.com/iamfy/archive/2012/09/20/2694977.html 一)概述: 1)从2.1版开始,Linux内核有了能力(capability)的概念,即它打破了UNIX/LINUX操作系统中超级用户/普通用户的概念,由普通用户也可以做只有超级用户可以完成的工作. 2)capability可以作用在进程上(受限),也可以作用在程序文件上,它与sudo不同,sudo只针对用户/程序/文件的概述,即sudo可以配置某个用户可以执行某个命令,可以更改某个文件,而capability是让某个程序拥有某种能力,例如: capability让/tmp/testkill程序可以kill掉其它进程,但它不能mount设备节点到目录,也不能重启系统,因为我们只指定了它kill的能力,即使程序有问题也不会超出能力范围. 3)每个进程有三个和能力有关的位图:inheritable(I),permitted(P)和effective(E),对应进程描述符task_struct(include/linux/sched.h)里面的cap_effective, cap_inheritable, cap_permitted,所以我们可以查看/proc/PID/status来查看进程的能力. 4)cap_effective:当一个进程要进行某个特权操作时,操作系统会检查cap_effective的对应位是否有效,而不再是检查进程的有效UID是否为0. 例如,如果一个进程要设置系统的时钟,Linux的内核就会检查cap_effective的CAP_SYS_TIME位(第25位)是否有效. 5)cap_permitted:表示进程能够使用的能力,在cap_permitted中可以包含cap_effective中没有的能力,这些能力是被进程自己临时放弃的,也可以说cap_effective是cap_permitted的一个子集. 6)cap_inheritable:表示能够被当前进程执行的程序继承的能力. Linux是一种安全操作系统,它给普通用户尽可能低的权限,而把全部的系统权限赋予一个单一的帐户-root。root帐户用来管理系统、安装软件、管理帐户、运行某些服务、安装/卸载文件系统、管理用户、安装软件等。另外,普通用户的很多操作也需要root权限,这通过setuid实现。 这种依赖单一帐户执行特权操作的方式加大了系统的面临风险,而需要root权限的程序可能只是为了一个单一的操作,例如: 绑定到特权端口、打开一个 只有root权限可以访问的文件。某些程序可能有安全漏洞,而如果程序不是以root的权限运行,其存在的漏洞就不可能对系统造成什么威胁。 从2.1版开始,内核开发人员在Linux内核中加入了能力(capability)的概念。其目标是消除需要执行某些操作的程序对root帐户的依赖。从2.2版本的内核开始,这些代基本可以使用了,虽然还存在一些问题,但是方向是正确的。 2.Linux内核能力详解 传统UNIX的信任状模型非常简单,就是"超级用户对普通用户"模型。在这种模型中,一个进程要么什么都能做,要么几乎什么也不能做,这取决于进程 的UID。如果一个进程需要执行绑定到私有端口、加载/卸载内核模块以及管理文件系统等操作时,就需要完全的root权限。很显然这样做对系统安全存在很 大的威胁。UNIX系统中的SUID问题就是由这种信任状模型造成的。例如,一个普通用户需要使用ping命令。这是一个SUID命令,会以root的权 限运行。而实际上这个程序只是需要RAW socket 建立必要ICMP数据包,除此之外的其它root权限对这个程序都是没有必要的。如果程序编写不好,就可能 被攻击者利用,获得系统的控制权。 使用能力(capability)可以减小这种风险。系统管理员为了系统的安全可以剥夺root用户的能力,这样即使root用户也将无法进行某些 操作。而这个过程又是不可逆的,也就是说如果一种能力被删除,除非重新启动系统,否则即使root用户也无法重新添加被删除的能力。 3.权限说明 Capabilities的主要思想在于分割root用户的特权,即将root的特权分割成不同的能力,每种能力代表一定的特权操作。例如: 能力CAP_SYS_MODULE表示用户能够加载(或卸载)内核模块的特权操作,而CAP_SETUID表示用户能够修改进程用户身份的特权操作。在Capbilities中系统将根据进程拥有的能力来进行特权操作的访问控制。 在Capilities中,只有进程和可执行文件才具有能力,每个进程拥有三组能力集,分别称为cap_effective, cap_inheritable, cap_permitted(分别简记为:pE,pI,pP),其中cap_permitted表示进程所拥有的最大能力集;cap_effective表示进程当前可用的能力集,可以看做是cap_permitted的一个子集;而cap_inheitable则表示进程可以传递给其子进程的能力集。系统根据进程的cap_effective能力集进行访问控制,cap_effective为cap_permitted的子集,进程可以通过取消cap_effective中的某些能力来放弃进程的一些特权。可执行文件也拥有三组能力集,对应于进程的三组能力集,分别称为cap_effective, cap_allowed 和 cap_forced (分别简记为fE,fI,fP) ,其中,cap_allowed表示程序运行时可从原进程的cap_inheritable中集成的能力集,cap_forced表示运行文件时必须拥有才能完成其服务的能力集;而cap_effective则表示文件开始运行时可以使用的能力。 Linux内核从2.2版本开始,就加进的Capabilities的概念与机制,并随着版本升高逐步得到改进。在linux中,root权限被分割成一下29中能力: CAP_CHOWN:修改文件属主的权限 CAP_DAC_OVERRIDE:忽略文件的DAC访问限制 CAP_DAC_READ_SEARCH:忽略文件读及目录搜索的DAC访问限制 CAP_FOWNER: 忽略文件属主ID必须和进程用户ID相匹配的限制 CAP_FSETID:允许设置文件的setuid位 CAP_KILL:允许对不属于自己的进程发送信号 CAP_SETGID:允许改变进程的组ID CAP_SETUID:允许改变进程的用户ID CAP_SETPCAP:允许向其他进程转移能力以及删除其他进程的能力 CAP_LINUX_IMMUTABLE:允许修改文件的IMMUTABLE和APPEND属性标志 CAP_NET_BIND_SERVICE:允许绑定到小于1024的端口 CAP_NET_BROADCAST:允许网络广播和多播访问 CAP_NET_ADMIN:允许执行网络管理任务 CAP_NET_RAW:允许使用原始 socket CAP_IPC_LOCK:允许锁定共享内存片段 CAP_IPC_OWNER:忽略IPC所有权检查 CAP_SYS_MODULE:允许插入和删除内核模块 CAP_SYS_RAWIO:允许直接访问/devport,/dev/mem,/dev/kmem及原始块设备 CAP_SYS_CHROOT:允许使用chroot()系统调用 CAP_SYS_PTRACE:允许跟踪任何进程 CAP_SYS_PACCT:允许执行进程的BSD式审计 CAP_SYS_ADMIN:允许执行系统管理任务,如加载或卸载文件系统、设置磁盘配额等 CAP_SYS_BOOT:允许重新启动系统 CAP_SYS_NICE:允许提升优先级及设置其他进程的优先级 CAP_SYS_RESOURCE:忽略资源限制 CAP_SYS_TIME:允许改变系统时钟 ...

2020-01-18 · 1 min · 133 words · -

Podman, Buildah, Skopeo

Podman, Buildah, Skopeo podman Podman是该工具套件的核心,用来替换Docker中了大多数子命令 (RUN,PUSH,PULL等) 。Podman无需守护进程,使用用户命名空间来模拟容器中的root,无需连接到具有root权限的 socket 保证容器的体系安全。 Podman专注于维护和修改OCI镜像的所有命令和功能,例如拉动和标记。它还允许我们创建,运行和维护从这些镜像创建的容器。 目前有很多可用的容器引擎,不过 Docker 最突出的竞争对手是由 Red Hat 开发的 Podman。与 Docker 不同,Podman 不需要守护进程,也不需要 root 特权,这是 Docker 长期以来一直存在的问题。从它的名字就可以看出来,Podman 不仅可以运行容器,还可以运行 Pod。Pod 是 Kubernetes 的最小计算单元,由一个或多个容器(主容器和所谓的边车)组成,Podman 用户在以后可以更容易地将他们的工作负载迁移到 Kubernetes。 Buildah Buildah 是套件中的 Build 工具,用来构建OCI镜像。虽然 Podman 也可以用户构建 Docker 镜像,但是构建速度超慢,并且默认情况下使用 vfs 存储驱动程序会消耗大量磁盘空间。 而 buildah bud (使用Dockerfile构建) 非常快,并使用覆盖存储驱动程序,可以节约大量的空间。 Buildah (https://buildah.io) 。Buildah 是 Red Hat 开发的一款工具,可以很好地与 Podman 配合使用。如果你已经安装了 Podman,可能会注意到 podman build 子命令,它实际上是经过包装的 Buildah。 Skopeo Skopeo是套件中镜像管理工具,允许我们通过推,拉和复制镜像来处理Docker和OC镜像。 https://zhuanlan.zhihu.com/p/77373246 除了 Docker 和 Podman 之外,还有其他容器引擎,但我认为它们没有出路或者都不适合用于本地开发。不过如果你想要对容器引擎有一个较为完整的了解,我们可以列出一些: LXD——是 LXC (Linux 容器)的容器管理器(守护进程)。这个工具提供了运行系统容器的能力,这些系统容器提供了类似于 VM 的容器环境。它比较小众,没有很多用户,所以除非你有特定的用例,否则最好使用 Docker 或 Podman。 CRI-O——如果你在网上搜索 cri-o 是什么东西,你可能会发现它被描述为一种容器引擎。不过,它实际上是一种容器运行时。除了不是容器引擎之外,它也不适合用于“一般”的情况。我的意思是,它是专门为 Kubernetes 运行时(CRI)而构建的,并不是给最终用户使用的。 rkt——rkt(“rocket”)是由 CoreOS 开发的容器引擎。这里提到这个项目只是为了清单的完整性,因为这个项目已经结束了,它的开发也停止了——因此它不应该再被使用。 ...

2020-01-18 · 1 min · 118 words · -

CentOS firewalld, firewall-cmd

‘CentOS firewalld, firewall-cmd’ Firewalld 使用区域和服务的概念。根据您将要配置的区域和服务,您可以控制允许或阻止与系统之间的流量。 可以使用 firewall-cmd 命令行实用程序配置和管理 Firewalld 。 在 CentOS 8 中, nftables 替代了 iptables,作为 firewalld 守护程序的默认防火墙后端。 防火墙区域 区域是预定义的规则集,用于指定计算机连接到的网络的信任级别。您可以将网络接口和源分配给区域。 以下是 FirewallD 提供的区域,根据区域的信任级别从不信任到信任: drop: 删除所有传入连接,而无任何通知。仅允许传出连接。 block: 拒绝所有传入连接,并带有一条 icmp-host-prohibited 消息 IPv4 和一条 icmp6-adm-prohibited 关于 IPv6n 的消息。仅允许传出连接。 public: 用于不受信任的公共区域。您不信任网络上的其他计算机,但是可以允许选择的传入连接。 external: 用于在系统充当网关或路由器时启用 NAT 伪装的外部网络。仅允许选择的传入连接。 internal: 当系统充当网关或路由器时,用于内部网络。网络上的其他系统通常是受信任的。仅允许选择的传入连接。 dmz: 用于非军事区中访问网络其余部分的计算机。仅允许选择的传入连接。 work: 用于工作机。网络上的其他计算机通常是受信任的。仅允许选择的传入连接。 home: 用于家用机器。网络上的其他计算机通常是受信任的。仅允许选择的传入连接。 Trusted: 接受所有网络连接。信任网络中的所有计算机。 centos 7 firewall # 启动守护程序 systemctl start firewalld --now # 查看版本 firewall-cmd --version # 查看状态 systemctl status firewalld.service # OR firewall-cmd --state # 查看默认区域 firewall-cmd --get-default-zone # firewall-cmd --zone=public --list-ports firewall-cmd --zone=public --add-port=8080/tcp firewall-cmd --zone=public --add-port=80/tcp --permanent firewall-cmd --zone=public --remove-port=8080/tcp 防火墙区域 默认的区域设置为 public ,并且所有网络接口都分配给该区域,当然您可以根据自己的需要修改默认区域。 默认区域是用于所有未明确分配给另一个区域的区域。 您可以通过键入以下内容查看默认区域: ...

2020-01-17 · 2 min · 285 words · -

伪共享 (false sharing)

伪共享 (false sharing) 伪共享的非标准定义为: 缓存系统中是以缓存行 (cache line) 为单位存储的,当多线程修改互相独立的变量时,如果这些变量共享同一个缓存行,就会无意中影响彼此的性能,这就是伪共享。 https://www.cnblogs.com/cyfonly/p/5800758.html

2020-01-13 · 1 min · 9 words · -

archlinux grub

archlinux grub parted flag For parted set/activate the flag bios_grub on the partition. parted -a optimal /dev/sda set 1 bios_grub on pacman -S grub # where /dev/sdX is the disk (not a partition) grub-install --target=i386-pc /dev/sdX grub-mkconfig -o /boot/grub/grub.cfg ### exit arch-chroot exit # 重启 reboot

2020-01-12 · 1 min · 46 words · -

tune2fs

tune2fs tune2fs命令 一.简介: tune2fs用来调整和查看ext2/ext3 (现在有ext4了) 文件系统的文件系统参数,Windows平台如果出现意外断电死机情况,下次开机一般都会出现系统自检。Linux系统当然也有文件系统自检,而且是可以通过tune2fs命令,自行定义自检周期及方式。 二.用法: 自己去man吧,man man,更健康。。。 常用选项说明: -l 查看文件系统信息 -c max-mount-counts 设置强制自检的挂载次数,如果开启,每挂载一次mount conut就会加1,超过次数就会强制自检 -i interval-between-checks[d|m|w] 设置强制自检的时间间隔[d天m月w周] -m reserved-blocks-percentage 保留块的百分比 -j 将ext2文件系统转换为ext3类型的文件系统 -L volume-label 类似e2label的功能,可以修改文件系统的标签 -r reserved-blocks-count 调整系统保留空间 -o [^]mount-option[,…] Set or clear the indicated default mount options in the filesystem. 设置或清除默认挂载的文件系统选项 (这一条是我需要的。) 三.例如: tune2fs -c 30 /dev/hda1 设置强制检查前文件系统可以挂载的次数 tune2fs -c -l /dev/hda1 关闭强制检查挂载次数限制。 #有些分区本身默认就是-1,也就是不检测 tune2fs -i 10 /dev/hda1 10天后检查 tune2fs -i 1d /dev/hda1 1天后检查 tune2fs -i 3w /dev/hda1 3周后检查 ...

2020-01-12 · 1 min · 100 words · -

ios iphone basic

ios iphone basic 儿童账户 APP 年龄限制设置 Family> 儿童账户> Screen Time> Content & Privacy Restrictions> Content Restrictions> Apps 关闭辅助触控, 关闭屏幕上的圆点 设置》通用》辅助功能》触控》辅助触控》关闭

2020-01-11 · 1 min · 20 words · -

ansible-pull

ansible-pull ansible-pull 该指令的使用涉及Ansible的另一种工作模式: pull模式 (Ansible默认使用push模式) 。这和通常使用的push模式工作机理刚好相反,其适用于以下场景: ①你有数量巨大的机器需要配置,即使使用高并发线程依旧要花费很多时间;②你要在刚启动的、没有网络连接的主机上运行Anisble。 ansible-pull命令使用格式如下: ansible-pull [options] [playbook.yml] 通过ansible-pull结合Git和crontab一并实现,其原理如下: 通过crontab定期拉取指定的Git版本到本地,并以指定模式自动运行预先制订好的指令。 具体示例参考如下: /20 * * * root /usr/local/bin/ansible-pull -o -C 2.1.0 -d /srv/www/king-gw/ -i /etc/ansible/hosts -U git:// git.kingifa.com/king-gw-ansiblepull » /var/log/ansible-pull.log 2>&1 ansible-pull通常在配置大批量机器的场景下会使用,灵活性稍有欠缺,但效率几乎可以***提升,对运维人员的技术水平和前瞻性规划有较高要求。

2020-01-11 · 1 min · 34 words · -

java 中的内省 introspector

java 中的内省 introspector 概述 经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以sun公司开发了一套API,专门用于操作java对象的属性。 内省(IntroSpector)是Java语言对JavaBean 类属性、事件的一种处理方法。 例如类A中有属性name,那我们可以通过getName,setName 来得到其值或者设置新的值。 通过getName/setName 来访问name属性,这就是默认的规则。 Java中提供了一套API 用来访问某个属性的getter/setter方法,通过这些API可以使你不需要了解这个规则,这些API存放于包java.beans 中。 一般的做法是通过类Introspector的getBeanInfo方法获取某个对象的BeanInfo信息,然后通过BeanInfo来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后我们就可以通过反射机制来调用这些方法。 我们又通常把javabean的实例对象称之为值对象,因为这些bean中通常只有一些信息字段和存储方法,没有功能性方法。 一个JavaBean类可以不当JavaBean用,而当成普通类用。JavaBean实际就是一种规范,当一个类满足这个规范,这个类就能被其它特定的类调用。一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。去掉set前缀,然后取剩余部分,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的。 内省访问JavaBean有两种方法: 通过PropertyDescriptor来操作Bean对象 public static void demo1() throws Exception { User user = new User(“zhangsan”, 21); String propertyName = “name”; // 直接指定要访问的属性 PropertyDescriptor pd = new PropertyDescriptor(propertyName, user.getClass()); // 获取到读方法 Method readMethod = pd.getReadMethod(); // 反射机制调用 Object invoke = readMethod.invoke(user, null); System.out.println(“名字: " + invoke); pd.getWriteMethod().invoke(user, “lisi”); invoke = readMethod.invoke(user, null); System.out.println(“名字: " + invoke); ...

2020-01-10 · 1 min · 199 words · -

junit

junit junit5 JUnit5的第一个可用性版本是在2017年9月10日发布的。 JUnit5架构 相比JUnit4,JUnit5由三个不同的子项目及不同的模块组成。 JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage JUnit Platform 启动Junit测试、IDE、构建工具或插件都需要包含和扩展Platform API,它定义了TestEngine在平台运行的新测试框架的API。 它还提供了一个控制台启动器,可以从命令行启动Platform,为Gradle和Maven插件提供支持。 JUnit Jupiter 它用于编写测试代码的新的编程和扩展模型。它具有所有新的Junit注释和TestEngine实现来运行这些注释编写的测试。 JUnit Vintage 它主要的目的是支持在JUnit5的测试代码中运行JUnit3和4方式写的测试,它能够向前兼容之前的测试代码。 https://tonydeng.github.io/2017/10/09/junit-5-tutorial-introduction/ 安装 你可以在Maven或Gradle项目中使用JUnit5,包含最小的两个依赖关系,即junit-jupiter-engince和junit-platform-runner。 <project> <properties> <junit.jupiter.version>5.5.2</junit.jupiter.version> <junit.platform.version>1.5.2</junit.platform.version> </properties> <dependencies> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>${junit.jupiter.version}</version> </dependency> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-runner</artifactId> <version>${junit.platform.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.jdbi</groupId> <artifactId>jdbi3-core</artifactId> <version>${jdbi.version}</version> </dependency> </dependencies> </project> import org.junit.jupiter.api.Test; public class AppTest { @Test public void Test() { System.out.println("foo"); } } Annotations 描述 ...

2020-01-09 · 1 min · 91 words · -

故障码类型 主动/静态,被动/偶发

故障码类型 主动/静态,被动/偶发 主动静态,说明这个故障一直存在,无法消除,被动偶发说明是以前有过,后来好了,比如你断电后需要设定门一键升窗,你设定好了就成被动偶发的。可以消除。 https://zhidao.baidu.com/question/1239311185193933419.html

2019-12-30 · 1 min · 4 words · -

Redis 持久化 RDB 和 AOF

Redis 持久化 RDB 和 AOF Redis本身的机制是 AOF 持久化开启且存在AOF文件时,优先加载AOF文件;AOF 关闭或者AOF文件不存在时,加载RDB文件;加载AOF/RDB文件城后,Redis启动成功;AOF/RDB文件存在错误时,Redis启动失败并打印错误信息 RDB快照持久化 RDB 持久化是通过快照的方式,即在指定的时间间隔内将内存中的数据集快照写入磁盘。在创建快照之后,用户可以备份该快照,可以将快照复制到其他服务器以创建相同数据的服务器副本,或者在重启服务器后恢复数据。RDB是Redis默认的持久化方式 快照持久化 RDB持久化会生成RDB文件,该文件是一个压缩过的二进制文件,可以通过该文件还原快照时的数据库状态,即生成该RDB文件时的服务器数据。RDB文件默认为当前工作目录下的dump.rdb,可以根据配置文件中的dbfilename和dir设置RDB的文件名和文件位置 # 设置 dump 的文件名 dbfilename dump.rdb # 工作目录 # 例如上面的 dbfilename 只指定了文件名, # 但是它会写入到这个目录下。这个配置项一定是个目录,而不能是文件名。 dir ./ 触发快照的时机 执行 save 和 bgsave 命令 配置文件设置 save <seconds> <changes>规则,自动间隔性执行bgsave命令 主从复制时,从库全量复制同步主库数据,主库会执行bgsave 执行 flushall 命令清空服务器数据 执行 shutdown 命令关闭 Redis 时,会执行 save命令 save 和bgsave命令 执行save 和bgsave命令,可以手动触发快照,生成RDB文件,两者的区别如下 使用save 命令会阻塞Redis服务器进程,服务器进程在RDB文件创建完成之前是不能处理任何的命令请求 而使用bgsave 命令不同的是,basave命令会fork一个子进程,然后该子进程会负责创建RDB文件,而服务器进程会继续处理命令请求 fork() 是由操作系统提供的函数,作用是创建当前进程的一个副本作为子进程 fork 一个子进程,子进程会把数据集先写入临时文件,写入成功之后,再替换之前的RDB文件,用二进制压缩存储,这样可以保证RDB文件始终存储的是完整的持久化内容 自动间隔触发 在配置文件中设置 save <seconds> <changes> 规则,可以自动间隔性执行bgsave命令 # SNAPSHOTTING ################################ # # Save the DB on disk: # # save <seconds> <changes> # # Will save the DB if both the given number of seconds and the given # number of write operations against the DB occurred. # # In the example below the behaviour will be to save: # after 900 sec (15 min) if at least 1 key changed # after 300 sec (5 min) if at least 10 keys changed # after 60 sec if at least 10000 keys changed # # Note: you can disable saving completely by commenting out all "save" lines. # # It is also possible to remove all the previously configured save # points by adding a save directive with a single empty string argument # like in the following example: # # save "" save 900 1 save 300 10 save 60 10000 # save <seconds> <changes>表示在seconds秒内,至少有changes次变化,就会自动触发gbsave命令 save 900 1 # 当时间到900秒时,如果至少有1个key发生变化,就会自动触发bgsave命令创建快照 save 300 10 # 当时间到300秒时,如果至少有10个key发生变化,就会自动触发bgsave命令创建快照 save 60 10000 # 当时间到60秒时,如果至少有10000个key发生变化,就会自动触发bgsave命令创建快照 RDB RDB 持久化 执行 rdb 持久化时, Redis 会fork 出一个子进程, 子进程将内存中数据写入到一个紧凑的文件中, 因此它保存的是某个时间点的完整数据。 ...

2019-12-23 · 5 min · 1026 words · -

DCEVM, HotSwapAgent

DCEVM, HotSwapAgent https://blog.csdn.net/u013613428/article/details/51499911 要高效的开发Java代码,那就必须要让java像js一样,修改过的代码可以实时的反应出来。要了解如何做到这一点,我们先要知道JVM是如何工作的: 我们知道,JAVA程序都是运行在java虚拟机上面 (当然JVM有两种类型,JDK和单纯的JRE,这里我们主要是指的JDK,因为只有JDK包含了debug功能,而我们只有在debug端口打开的情况下才能实现run time class load) ,我们的写的每一个Java文件,会被编译器编译成为class文件,然后根据选择不同的打包选择,比如说 (jar, war, ear) ,被打包存放到系统的classpath中。在运行一个java程序的时候,会有几个步骤, 包括装载,链接,初始化,翻译 (在翻译成机器码的时候同时会对代码进行优化,inline) ,运行,就如下图 这里的关键,就是这个classloader。所有的类都会在jvm中生成为class对象,存放在内存当中, (这里,主要分成两部分,常量池和方法字节码) 当我们的程序生成一个类的实例或instance时候,就会根据这个类对象,分配和初始化内存用于存储对象的field,然后在调用对象方法的时候,则从class对象中获取方法字节码,如下图: 因此,如果我们能够在JVM里面途欢这个class对象,那么我们创建的所有object或instance,在调用函数的时候,就可以动态获得你修改之后的代码。如下图: hotswap的原理,就是替换jvm里面的class对象. Sun 在2002年把这项技术引入到java 1.4的JVM中,Hotswap需要和debuggerAPI一起协同工作,我们可以通过debugger来更新jvm里面同名的class bytecode 因此,这也就限制了,我们在使用hotswap的时候,必须使用debug mode.因此也就限制了java app必须是运行在jdk上,而不是jre上,JAVA_HOME必须指向JDK。 说了这么多理论,回到我们最初的话题,如何做到hotswap呢,步骤很简单: 用debug模式attach我们的app 修改你的java文件,并且编译 这时,神奇的事情发生了,如下图 我们的class被reload了,我们可以不用重新把app部署到服务器上就可以直接看修改代码之后的结果。 等等,天底下有这么容易的事情吗?!这个solution是有缺陷的,那就是我们只能简单修改class method的内容,如果我们新添加了Method,field,或者在method里面引用了新的lib,增加了Import语句,那么对不起,你会看到: hot swap失败了。 那么有没有什么解决方案呢?有!收费的JRebel,或者免费的HotSwapAgent+DCEVM 让我们来看看什么是DCEVM: https://dcevm.github.io/ The Dynamic Code Evolution VirtualMachine (DCEVM)is a modification of the Java HotSpot(TM) VM that allows unlimited redefinitionof loaded classes at runtime. The current hotswapping mechanism of the HotSpot(TM) VM allows only changing methodbodies. Our enhanced VMallows adding and removing fields and methods as well as changes to the supertypes of a class. ...

2019-12-17 · 1 min · 177 words · -

awk、grep、sed

awk、grep、sed awk、grep、sed是linux操作文本的三大利器,也是必须掌握的linux命令之一。三者的功能都是处理文本,但侧重点各不相同,其中属awk功能最强大,但也最复杂。 grep适合单纯的查找或匹配文本, sed适合编辑匹配到的文本, awk适合格式化文本,对文本进行较复杂格式处理。 awk https://blog.wiloon.com/?p=3738 sed https://blog.wiloon.com/?p=2838 grep https://blog.wiloon.com/?p=468 https://thief.one/2017/08/12/1/

2019-12-11 · 1 min · 12 words · -

Funtoo

Funtoo Funtoo Linux 是由 Daniel Robbins (Gentoo Linux的创始人和前项目领袖) 和一个核心开发团队基于 Gentoo 的发行版,它基于一个简单的愿景, 那就是提升 Gentoo Linux 中的核心技术。 https://imtx.me/archives/923.html https://www.funtoo.org/Welcome

2019-12-09 · 1 min · 17 words · -

kafka 分区数

kafka 分区数 Kafka的分区数是不是越多越好? 分区多的优点 kafka使用分区将topic的消息打散到多个分区分布保存在不同的broker上,实现了producer和consumer消息处理的高吞吐量。Kafka的producer和consumer都可以多线程地并行操作,而每个线程处理的是一个分区的数据。因此分区实际上是调优Kafka并行度的最小单元。对于producer而言,它实际上是用多个线程并发地向不同分区所在的broker发起Socket连接同时给这些分区发送消息;而consumer,同一个消费组内的所有consumer线程都被指定topic的某一个分区进行消费。 所以说,如果一个topic分区越多,理论上整个集群所能达到的吞吐量就越大。 分区不是越多越好 分区是否越多越好呢?显然也不是,因为每个分区都有自己的开销: 一、客户端/服务器端需要使用的内存就越多 Kafka0.8.2之后,在客户端producer有个参数 batch.size,默认是16KB。它会为每个分区缓存消息,一旦满了就打包将消息批量发出。看上去这是个能够提升性能的设计。不过很显然,因为这个参数是分区级别的,如果分区数越多,这部分缓存所需的内存占用也会更多。假设你有10000个分区,按照默认设置,这部分缓存需要占用约157MB的内存。而consumer端呢?我们抛开获取数据所需的内存不说,只说线程的开销。如果还是假设有10000个分区,同时consumer线程数要匹配分区数(大部分情况下是最佳的消费吞吐量配置)的话,那么在consumer client就要创建10000个线程,也需要创建大约10000个Socket去获取分区数据。这里面的线程切换的开销本身已经不容小觑了。 服务器端的开销也不小,如果阅读Kafka源码的话可以发现,服务器端的很多组件都在内存中维护了分区级别的缓存,比如controller,FetcherManager等,因此分区数越多,这种缓存的成本就越大。 二、文件句柄的开销 每个分区在底层文件系统都有属于自己的一个目录。该目录下通常会有两个文件: base_offset.log和base_offset.index。Kafak的controller和ReplicaManager会为每个broker都保存这两个文件句柄(file handler)。很明显,如果分区数越多,所需要保持打开状态的文件句柄数也就越多,最终可能会突破你的ulimit -n的限制。 三、降低高可用性 Kafka通过副本(replica)机制来保证高可用。具体做法就是为每个分区保存若干个副本(replica_factor指定副本数)。每个副本保存在不同的broker上。期中的一个副本充当leader 副本,负责处理producer和consumer请求。其他副本充当follower角色,由Kafka controller负责保证与leader的同步。如果leader所在的broker挂掉了,contorller会检测到然后在zookeeper的帮助下重选出新的leader——这中间会有短暂的不可用时间窗口,虽然大部分情况下可能只是几毫秒级别。但如果你有10000个分区,10个broker,也就是说平均每个broker上有1000个分区。此时这个broker挂掉了,那么zookeeper和controller需要立即对这1000个分区进行leader选举。比起很少的分区leader选举而言,这必然要花更长的时间,并且通常不是线性累加的。如果这个broker还同时是controller情况就更糟了。 如何确定分区数量呢? 可以遵循一定的步骤来尝试确定分区数: 创建一个只有1个分区的topic,然后测试这个topic的producer吞吐量和consumer吞吐量。假设它们的值分别是Tp和Tc,单位可以是MB/s。然后假设总的目标吞吐量是Tt,那么分区数 = Tt / max(Tp, Tc) 说明: Tp表示producer的吞吐量。测试producer通常是很容易的,因为它的逻辑非常简单,就是直接发送消息到Kafka就好了。Tc表示consumer的吞吐量。测试Tc通常与应用的关系更大, 因为Tc的值取决于你拿到消息之后执行什么操作,因此Tc的测试通常也要麻烦一些。 ———————————————— 版权声明: 本文为CSDN博主「AlferWei」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接: https://blog.csdn.net/OiteBody/article/details/80595971

2019-11-27 · 1 min · 42 words · -

基站定位

基站定位 MCC: 国家码 MNC: 运营商码 LAC: 位置区码, 大区 CellID: 基站塔码, 小区

2019-11-26 · 1 min · 11 words · -