原我的项目中诸如 用户浏览文章记录等写多读少的表,数据量亿级以上,用MySQL存储性能不太佳,所以尝试迁徙到 NoSQL 数据库,比照后抉择了 ScyllaDB。
ScyllaDB介绍
Scylla是一个开源、分布式、去中心化、弹性可扩大、高可用、容错、可调一致性、面向行的数据库。
Scylla应用C++从新实现了Cassandra,以进步性能并利用多核服务。它解决了Apache Cassandra的一些陷阱,是Apache Cassandra的嵌入式替换数据库,这两个数据库之间的驱动程序相互兼容。
Hbase与ScyllaDB
- Scylla是p2p架构,无单点生效问题,Hbase是主从构造,须要选主,保护主从关系;
- Scylla是AP零碎,也能够通过调整参数使它成为CP零碎(只有R+W>N),HBase是CP零碎,对数据有强一致性需要就应用HBase;
- Scylla是一个数据存储和数据管理系统。HBase只负责数据管理,它须要配合HDFS和zookeeper来搭建集群;
- Scylla写性能好一些,因为数据哈希较扩散,读性能不如HBase。HBase写过程比拟繁琐,但其数据在regin内是排序的,读性能更好;
- 两个都适宜寄存 time-series data,例如传感器数据,网站拜访,用户行为,股市交易数据等;
- Scylla善于数据接入,因为写性能比拟好。
Docker搭建ScyllaDB集群
docker run --name scylla-node2 -p 8042:9042 -p 8160:9160 -p 1000:10000 -p 8180:9180 -v /data/scylladb2:/var/lib/scylla -d scylladb/scylla --seeds="$(docker inspect --format='{{ .NetworkSettings.IPAddress }}' scylla)"docker run --name scylla-node3 -p 10042:9042 -p 10160:9160 -p 1100:10000 -p 10180:9180 -v /data/scylladb3:/var/lib/scylla -d scylladb/scylla --seeds="$(docker inspect --format='{{ .NetworkSettings.IPAddress }}' scylla)"docker run --name scylla-node4 -p 11042:9042 -p 11160:9160 -p 1200:10000 -p 11180:9180 -v /data/scylladb4:/var/lib/scylla -d scylladb/scylla --seeds="$(docker inspect --format='{{ .NetworkSettings.IPAddress }}' scylla)"
接下来先介绍Cassandra的根底信息。
数据模型
Cassandra的数据模型借鉴了谷歌BigTable的设计思维,有以下几个概念:
- 键空间(keyspace):相当于关系型数据库模型中的database,是最上层的命令空间。
- Key:对应 SQL 数据库中的主键,在 Cassandra 中,每一行数据记录是以 key/value 的模式存储的,其中 key 是惟一标识。
- 列族:列族是有序行汇合的容器,反过来,每一行都是有序的列汇合。
- 列(column):最根本的数据结构单元,由name和value组成,其蕴含工夫戳和生存工夫属性(能够通过writetime()或者ttl()函数查看。
- 超级列(super column):超级列是一个非凡列,因而它也是一个键值对。然而超级列存储子列的映射。Cassandra 容许 key/value 中的 value 是一个 map(key/value_list),即某个 column 有多个子列。
Cassandra中Keyspace的根本属性有
- 复制因子 : 它是群集中将接管雷同数据正本的计算机数量.
- 正本搁置策略 : 它只不过是将复制品置于戒指中的策略.咱们有策略,例如简略策略(机架感知策略),旧网络拓扑策略(机架感知策略)和网络拓扑策略 (数据中心共享策略).
- 列族 : Keyspace是一个或多个列族列表的容器.反过来,列族是行汇合的容器。每行蕴含有序列,列族示意数据的构造,每个键空间至多有一个且通常很多列族。
创立Keyspace的语法如下
CREATE KEYSPACE Keyspace name WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 3};
三种次要的键
Cassandra次要由三种键:
- primary key:用于确定一条数据的键,由partition key 和clustering key组成(clustering key不是必要的)
- partition key:用于数据分区。从群集读取或写入数据时,将应用一个名为Partitioner的函数来计算分区键的哈希值。该哈希值用于确定蕴含该行哈希值的节点
- clustering key:次要用于进行范畴查找及排序(相当于SortedMap中的key)
Cassandra会对partition key做一个hash计算,并本人决定将记录放到哪个NODE,partition key 能够是繁多主键,也能够是复合主键,然而主键不能反复(主键反复的记录很可能会被。clustering key次要用于进行Range Query(范畴查找),并且应用的时候须要依照建表程序进行提供信息。
CREATE TABLE brows_record_by_target ( target_id bigint, create_user bigint, TYPE text, app_id text, create_time timestamp, id bigint, PRIMARY KEY ((target_id, TYPE, app_id), create_user, create_time))WITH CLUSTERINGORDER BY (create_user DESC, create_time DESC);
其中(target_id, TYPE, app_id)是分区键,create_user, create_time是汇集键,整个组合成PRIMARY KEY。
外围组件
Cassandra的外围组件包含:
Gossip:点对点的通信协定,用来相互交换节点的地位和状态信息。当一个节点启动时就立刻本地存储Gossip信息,但当节点信息发生变化时须要荡涤历史信息,比方IP扭转了。通过Gossip协定,每个节点定期每秒替换它本人和它曾经替换过信息的节点的数据,每个被替换的信息都有一个版本号,这样当有新数据时能够笼罩老数据,为了保障数据交换的准确性,所有的节点必须应用同一份集群列表,这样的节点又被称作seed。
Partitioner:负责在集群中调配数据,由它来决定由哪些节点搁置第一份的copy,个别状况会应用Hash来做主键,将每行数据分布到不同的节点上,以确保集群的可扩展性。
Replica placement strategy:复制策略,确定哪个节点搁置复制数据,以及复制的份数。
Snitch:定义一个网络拓扑图,用来确定如何搁置复制数据,高效地路由申请。
cassandra.yaml:主配置文件,设置集群的初始化配置、表的缓存参数、调优参数和资源应用、超时设定、客户端连贯、备份和平安
数据分布
从Cassandra1.2开始,Cassandra每个节点能够领有很多个token(哈希范畴)。这种新的模式叫做虚构节点。虚构节点容许每个节点领有很多集群中哈希范畴。虚构节点也是用一致性哈希散布数据,然而用它却不须要生成和调配令牌。每个节点依据配置的虚构节点从哈希环中随机获取m个虚构节点(m为配置的虚构节点数)。
应用虚构点的益处
- 无需计算和调配集群中每个节点的token。
- 增加或者删除节点时,集群会主动从新均衡负载。当一个节点退出集群,它将摊派来自集群中其余节点的局部数据;如果某个节点产生故障,则在该节点上的数据将会平均分配到集群中的其余节点
- 重建死掉的节点更快。
- 容许同一集群内应用不同性能的机器
CQL
CQL的简略应用
CQL具体指南
对标SQL差异化
- 反对了json形式的select\insert
- update执行如果不存在会新增
- 更新where条件必须蕴含所有主键,且不能更新类型为static的字段
- 增删改查必须在主键列上 ,对于(A,B)模式的主键,如果查问条件不带分区键A,则查问语句须要开启allow filtering。
- partition key字段过多会对当前的查问造成很大困扰,在建表的时候首先肯定要思考好数据模型,免得前期掉坑
查问限度
- 在利用主键进行查问时,因为 partition key 是 hash 实现的,所以只能用=;
而 clustering key, 是 sortedMap 实现的,能够用做范畴查找与等号查找。例如:定义
PRIMARY KEY ((mainland), state, uid)
,则(mainland), state, uid
形成联结主键,其中 mainland 是 partition key ,而 state 和 UID 是 clustering key。select * from users where mainland = 'northamerica' and state > '1' and state < '5';
- 复合的partition key 查问时则要满足key_part_one=' ' and key_part_two =' '
此外,Cassandra 整体数据能够了解成一个微小的嵌套的Map。 只能按程序一层一层的深刻,不能跳过两头某一层。例如:
select * from users where location = 'shanghai' and uid < 5;
因为没有提供state的信息,不可行。
总之,Cassandra 中的存储,是2-level nested Map(2级嵌套map):Partition Key –> Custering Key –> Data
索引查问
索引:索引能够创立在除了 partition key 之外所有的列上,当然有些类型除外,例如汇合类型。采纳索引进行查问时,具体限度为:
- 索引列只能够用=号查问
- 如果查问条件里,有一个是依据索引查问,那其它非索引非主键字段,能够通过加一个ALLOW FILTERING来过滤实现。例如
SELECT * FROM user WHERE c>0 ALLOW FILTERING;
总结,在某一列加了索引后,某种程度上相当于把该列变成了partition key。