cassandra权威指南读书笔记--读写数据
写
cassandra除了轻量级事务,不支持别的事务。cassandra是追加写,写的速度非常快。cassandra还有hint日志,这个数据库总是可写的,而且单个列的写操作是原子的。
hint并不是一定写在协调节点,一般是写在下线节点的某个非副本的邻居节点。
写一致性
ANY:写hint也算成功
ONE:写hint和memtable才算成功。
协调节点会根据keyspace的副本数确定哪些是副本节点,如果副本节点不够满足一致性级别,直接报错。多DC时,客户端发请求到协调节点,协调节点同时会转发请求到所有DC的一个协调节点。如果涉及别的DC的一致性级别,对应节点会响应结果给原协调节点。
commitlog文件名格式:CommitLog-<version>-<timestamp>.log的模式命名。
version是commitlog格式的一个整数。cassandra 3.0的版本提交日志的格式是6。org.apache.db.commitlog.CommitLogDescriptor可以根据cassandra版本查到commitlog版本。
SSTable
每个keyspace有一个目录,每个目录下面有对应的表的目录,目录名由表名+UUID组成的,UUID是用来区别不同schema的表,因为表结构可能会变。表的目录下面是SSTable。
SSTable包含多个文件,这些文件采用通用的命名规则:
<version>-<generation>-<implementation>-<component>.db
version是一个两字符序列,表示SSTable格式的主\次版本。可以在org.apache.io.sstable.Descriptor
类中了解不同的SSTable格式版本。
generation 是一个索引数,每次为一个表创建一个新的SSTable时,索引数就会递增。
implementation 是实现org.apache.io.sstable.format.SSTableWriter接口的一个引用。比如cassandra 3.0,这个值是“big",会引用org.apache.cassandra.io.sstable.format.big.BigFormat类中的”Bigtable 格式“
component包含多种,3.0为例:
*-Data.db
存储实际的数据的文件,cassandra备份只保留这些文件。
*-CompressionInfo.db
提供Data.db文件压缩相关的元数据,包含有关未压缩的数据长度,块偏移量和其他压缩信息的信息
*-Digest.adler32
包含*-Data.db文件的一个校验和
*-Filter
包含这个SSTable的布隆过滤器
*-Index.db
提供相应的*-Data.db文件中的行和列的偏移位置
summary.db:索引的抽样,用来加速读取的
Statistics.db:存储有关SSTable的统计信息,nodetool tablehistograms命令将使用这些信息。
TOC.txt:该文件存储对应SSTable 所有组件的列表
轻量级事务 LWT lightweight transaction
限制:
1、必须在一个分区下。
2、每个事务由一个读写组成,读后写。也叫比较和设置,只有比较成功才会完成设置。类似CAS。
3、事务失败,会提示失败,会返回尝试更新的值,可以选择重试或者撤销。比如当你期望的值和读到的值不一样。
4、不支持using timestamp
insert要用if not exist
update要用if x=y
LWT的客户端时,可以使用wasApplied()来看语句是否成功。
LWT还另外支持串行一致性:serial和local_serial。
如果在查询的时候,读取的数据是一个未提交事务的一部分的时候,它会根据串行一致性级别提交事务。
批处理
支持多个分区,限制:
1、批处理只能包含修改语句(insert,update,delete)
2、批处理具有原子性。如果一个批处理被接受,最终一定会全部成功,batchlog。(3.0之前是unbatchlog,没有batchlog)
3、一个批处理中,分区所有更新会独立完成,可能会批处理完成之前读道不同分区的修改结果。
4、批处理带LWT,只能是在一个分区内。
5、计数器修改只能用于一种叫计算器批处理的方式。计算器批处理只能包含计数器修改。
批处理(batchlog方式)可能会降低性能,带来GC压力。
批处理底层实现:
协调器接受了批处理请求后,会将批处理请求的副本发给2个节点,副本存在system.batchlog。然后协调节点执行完批处理中所有的语句后,会删除其它节点的batchlog。
如果协调器执行失败,每分钟,每个节点会检查是否有应该完成的批处理。检查的时候会检查batchlog的时间戳和超时时间,只有才超时时间之后的才会reply,这样是防止重放正在执行的批处理。超时可以通过“cassandra.batchlog.replay_timeout_in_ms”来设置,如果没有设置,默认值write_request_timeout_in_ms的两倍。如果reply成功,会删掉对应的batchlog。
发给2个节点batchlog,存储batchlog的节点的选择其实只是找若干个尽可能不在同一个机架上的节点,主要是为了可靠性。
总结:
如果batch log写入失败,那么批处理全部失败。
如果batch log写入成功,即使某个写没有成功,cassandra也会(在gc_grace_seconds之前)一直回放batch log,保证最终全部成功。
注意:
表的gc_grace_seconds配置会影响batch的回放。在回放batch时,会检查涉及的所有表的gc_grace_seconds,如果当前时间已经超出了其中某个表的gc_grace_seconds,则整个batch都不会回放直接删除。另外,如果表的gc_grace_seconds为0,会收到警告提示。
失败:默认50k,batch_size_fail_threshold_in_kb
告警:默认5k,batch_size_warn_threshold_in_kb
counter因为不是幂等操作,不支持原子性的batch
正常写和批处理写会有并发问题。
LWT 超时后,后台batchlog 和正常写得看下代码,应该是会导致直到gc_grace_seconds后不在重试。
读
如果读到的数据不一致,会返回时间戳最新的那一条数据。然后cassandra会在后台完成读修复。如果本节点过滤墓碑,墓碑时间超过gc_grace_seconds,那么返回给协调节点的时候,是不带墓碑数据,如果不一致,可能会出现僵尸数据。
一致性级别没有ANY。如果一致性级别是ONE,而且多副本数据不一致,会先返回第一个查询到的节点数据,再在后台触发读修复。
读请求和写类似,也是协调节点接受请求,然后再转发到别的DC,不过只有一个DC只会选一个最快的节点完全读,其他读摘要。如果摘要和完全读计算的摘要的结果一致,就直接返回完全读的结果。如果不一致,就会完成一个读修复。
单节点完全读查询:
1、行缓存
如果行缓存没有则
2、检查键缓存查找索引
3、检查memtable。***一个给定的表只有一个memtable***
4、检查SSTable。有很多特性优化SSTable的搜索:键缓存,布隆过滤器,SSTable索引和摘要索引。
a.用布隆过滤器确定请求的分区在不在给定的SSTable中,如果不在就不必搜索这个SSTable。
b.如果通过布隆过滤器检验,就检查键缓存。键缓存是个Map,key=SSTable的文件描述符和分区键的组合,value=SSTable文件中的偏移位置。
c.如果没在键缓存命中,使用磁盘上存储的二级索引找到这个偏移位置。第一级是分区摘要,用来得到第二级索引的偏移位置,然后在第二级索引(分区索引)中搜索分区键,从而得到分区键在SSTable中的偏移位置。
d.找到分区键的偏移位置,就开始读数据,一旦从所有的SSTable读完数据,取各个列的最新时间戳的值,然后合并SSTable和memtable的数据。所有的墓碑都会被过滤掉,只剩下去除掉墓碑后的数据。
c.如果开启行缓存,会把数据写到行缓存中。
e.返回结果给协调节点。
摘要读取和上面一样,只是增加一步计算摘要的结果,返回给协调节点的也是摘要。
布隆过滤器优化:可以为每个表设置bloom_filter_fp_chance属性来控制布隆过滤器报告的误报率,不过会增加额外的内存消耗。
读修复
实现:协调节点向所有的副本节点发出一个完全读请求。协调节点需要为每一列选个值合并,它会比较副本返回值,返回有最新时间戳的值。(每个副本返回值如果有墓碑,而且墓碑时间超过gc_grace_seconds,副本返回数据会过滤掉墓碑,没超过就会连墓碑一起返回。)如果时间戳也一样,会按照字典排序,选择最大的值。合并后的数据,就是返回给客户端的值。
读修复会根据一致性级别决定在返回客户端之前或者之后完成读修复,比如Quorum或者all,就会在返回给客户端之前完成。如果是one,大概率在返回客户端之后修复。对于给定的表,读操作是否会导致后台读修复的几率由read_repair_chance和dc_local_read_repair_chance确定(当然还是先保证一致性级别,做修复,然后再由这两个参数确定)
函数和聚集
user-defined functions,UDF,用户自定义函数 (3.0起,UDF会在单独的沙箱运行)
user-defined aggregates,UDA,用户自定义聚集
user-defined types,UDT,用户自定义类型
原生函数和聚集:count,min,max,sum,avg
分页:limit,paging(2.0引入,自动分页,客户端可以请求一个查询返回的数据的一个子集)
预测重试:SpeculativeExecutionPolicy
删除
删除使用的是墓碑机制,是因为Cassandra自身的持久,最终一致和分布式设计。如果像RDBMS去设计直接删除,如果某个节点挂了,那么后来节点恢复了,这个节点就错过了删除,还保留了数据,可能会把已经删除的数据修复回来。
gc_grace_seconds主要是让有足够的时间去把挂掉的节点恢复。默认是10天,然后就会运行一个合并,将墓碑回收,从而释放空间。
由于SSTable是不可变的,并不是从SSTable删除数据。而是合并时,统计墓碑,对合并数据排序,在排序后的数据上创建新索引,将已合并,已排序的,并有索引的数据写到一个新文件。然后删除老文件。
cassandra权威指南读书笔记--读写数据的更多相关文章
- cassandra权威指南读书笔记--Cassandra架构(2)
环和令牌cassandra的数据管理是用一个环来表示.为环中的每个节点分配一or多个数据范围,用token描述.token由64位整数ID表示,范围-2^(63)~2^(63)-1.使用对分区键进行一 ...
- cassandra权威指南读书笔记--数据建模
没有join操作.有轻量级事务和批处理,但是没有外键等.反规范化.3.0支持物化视图,允许在一个表上创建数据的多个物化视图.使用cassandra要从查询入手,而不是先从数据模型开始.先对查询建模,然 ...
- cassandra权威指南读书笔记--Cassandra架构(1)
结构 集群-->数据中心-->机架-->节点. cassandra尽可能将数据副本存在多个数据中心,然后读取(查询路由到)尽可能在本地数据中心. 为了去中心化和分区容错性,使用gos ...
- cassandra权威指南读书笔记--客户端
DataStax驱动最成熟.默认,驱动程序会使用第一个连接的节点作为支持的版本协议.如果集群存在高低版本的节点(比如升级场景),如果驱动先连接不同不同版本的节点,可能会出现不兼容.驱动支持压缩客户端和 ...
- cassandra权威指南读书笔记--安全
认证和授权driver,JMX和cassandra服务器支持SSL/TLS,cassandra节点间也支持SSL/TLS.密码认证器cassandra还支持自定义,可插拔的认证机制.默认的认证器:or ...
- cassandra权威指南读书笔记--性能调优
cassandra自带测试工具cassandra-stress.nodetool proxyhistograms可以在多个节点运行,发现最慢的协调节点.nodetool tablehistograms ...
- cassandra权威指南读书笔记--监控&维护
cassandra SLF4J API记录日志,具体采用Logback实现.在终端启动cassandra时,可以向程序输入-f,就能在终端看到这个输出.Java Mangement Extension ...
- cassandra权威指南读书笔记--配置cassadnra
配置集群时,要求所有节点的集群名,分区器,snitch必须相同.种子节点最好相同. 种子节点:最好每个DC,配置2个,这样即使一个DC中一个种子节点挂了,仍然有一个中子节点可用.种子节点被认为是最先加 ...
- cassandra权威指南读书笔记--Cassandra架构(3)
分阶段事件驱动架构 SEDASEDA(Staged Event-Driven Architecture)的核心思想是把一个请求处理过程分成几个Stage,不同资源消耗的Stage使用不同数量的线程来处 ...
随机推荐
- 记一次Hadoop安装部署过程
实验名称:Hadoop安装部署 一.实验环境: 虚拟机数量:3个 (1个master,2个slave:slave01,slave02) 主节点master信息: 操作系统:CentOS7.5 软件包位 ...
- MAC与ARP缓存中毒介绍
ARP 协议 用于地址解析,请求MAC地址. arp -a 或者 -n 查看ARP缓存表 ls(ARP) 查看scapy里的协议字段 ARP缓存中毒原理 ARP收到ARP请求报文,会将发送方的mac地 ...
- Azure Terraform(三)部署 Web 应用程序
一,引言 上一节关于 Terraform 的文章讲到 Terraform 使用到的一些语法,以及通过演示使用 Terraform 在Azure 上部署资源组,极大的方便了基础设施实施人员,也提高了基础 ...
- user&group_management.md
登录shell bin/bash sbin/nologin useradd 的参数 -c comment 用户的注释性信息 -u UID 指定用户的UID -g initia ...
- 八:架构,搭建,WAF
WAF防护分析 什么是WAF应用 如何快速识别WAF 识别WAF对于安全测试的意义 CMS识别技术 源码获取技术 架构信息获取 站点搭建分析 搭建习惯-目录型站点 sti.blcu-bbs 目录型站点 ...
- Netty源码解析 -- FastThreadLocal与HashedWheelTimer
Netty源码分析系列文章已接近尾声,本文再来分析Netty中两个常见组件:FastThreadLoca与HashedWheelTimer. 源码分析基于Netty 4.1.52 FastThread ...
- 【Redis】Redis基础 - Redis安装启动测试
Redis基本 - 安装 文章目录 Redis基本 - 安装 Linux下安装Redis Docker 方式 Github 源码编译方式 直接安装方式 Windows下Redis安装 记录 - Red ...
- leetcode 940. 不同的子序列 II (动态规划 ,字符串, hash,好题)
题目链接 https://leetcode-cn.com/problems/distinct-subsequences-ii/ 题意: 给定一个字符串,判断里面不相同的子串的总个数 思路: 非常巧妙的 ...
- 基础练习(上) - 蓝桥杯(Python实现)
闰年判断: 题目: 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个年份,判断这一年是不是闰年. 当以下情况之一满足时,这一年是闰年: 1. 年份是4的倍数而不是100的倍数 ...
- oracle常用hint添加
1.视图添加索引 /* Formatted on 2020/1/6 下午 04:46:37 (QP5 v5.163.1008.3004) */ SELECT /*+index(VIEW_NAME.TA ...