《《读写机制调研》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《读写机制调研》PPT课件.ppt(34页珍藏版)》请在三一办公上搜索。
1、Cassandra读写机制调研,在数据的读取过程中,Cassandra会根据需要读取的ColumnFamily查询该ColumnFamily下的Memtable以及所有的SSTable,合并查询的结果,将最新的结果返回给客户端。读取操作根据一致性级别分为两类:强读取弱读取,Cassandra的数据读取机制,对于每一个读取命令,Cassandra的执行流程如下:从集群中找出一台最适合读取的服务器。从最适合读取的服务器读取数据如果最适合读取的服务器是本机,对本机的数据进行异步读取如果最适合读取的服务器不是本机,向该服务器请求需要读取的数据,并根据一定概率计算是否进行读修复操作(这里读修复操作异步执
2、行,不会等待读修复操作完毕后再将结果返回客户端)等待结果返回将返回的结果返回给客户端,弱读取,对于每一个读取命令,Cassandra的执行流程如下:从集群中找出一台最适合读取的服务器。向该服务器请求需要读取的数据。根据读取一致性级别,从集群中找出其他需要读取的服务器。向其他需要读取的服务器请求需要读取数据的摘要信息,用于对比多台机器之间数据是否一致。等待符合读取一致性要求结果的返回。从不同服务器返回的结果,对比数据是否一致,对于不一致的数据,进行QUORUM级别的读修复操作。将最终结果返回给客户端。,强读取,TableColumnFamilyStore 对象的集合,可以通过 column fa
3、mily 的名字查找到对应的 CFSColumnFamilyStoreDataTracker 关于该ColumnFamily的信息一个 Memtable 对象。该对象保存了最近的对该 CFS 中的 Column family 的修改,这些修改还没有被 flush 到磁盘上。一个 SSTableTracker 对象。这是一个 SStableReader 对象的集合,每个 SSTableReader 对象维护了关于磁盘上的 CF 数据的必要信息。,与数据模型相关的数据结构,Commitlog先写日志再写数据数据写入Memtable前需要由CommitLogExecutorService线程先写Co
4、mmitlog CommitlogHeader记录了CF的脏标志位和该CF的恢复起始偏移位置。CommitlogSegment记录了变更的RowMutation信息。MemtableConcurrentNavigableMap,这个哈希表用于从 row-key 查找对应的 ColumnFamily 对象。,与数据模型相关的数据结构(续),CassandraServerpublic List get_slice(ByteBuffer key,ColumnParent column_parent,SlicePredicate predicate,ConsistencyLevel consisten
5、cy_level)Exception:InvalidRequestExceptionUnavailableExceptionTimedOutException,读操作thrift接口,判断是否对指定ColumnFamily具有读权限,如果没有该权限,则抛出InvalidRequestException异常 private Map multigetSliceInternal取得ColumnFamily的元数据判断predicate里存储的是column name集合还是范围,构造不同Command集合,每个Key具有一个Command对象private Map getSlice(commands
6、,consistency_level),get_Slice,根据一致性级别和构造出的读取命令从指定ColumnFamily中读取数据readColumnFamily(未来可支持每行多个ColumnFamily,目前仅支持一行)如果一致性级别为ANY,抛出InvalidRequestException异常通过调度,执行StorageProxy.read(commands,consistency_level)取出行数据,可能抛出TimeoutException和IOException两种异常。如果处于BootstrapMode(集群joining状态),则抛出UnavailableExceptio
7、n调用StorageProxy的fetchRow取出行数据根据读操作命令从返回结果中取出指定column数据,getSlice,执行本地和远程读取操作,阻塞等待结果返回针对每个Command,执行如下读取操作:取出负责指定key的目前活着的节点将其按与本地节点之间距离排序判断目前活着的节点是否符合一致性要求向最近的节点发送读取数据请求。(如果之前回复的节点只有一个,则继续下一个读命令的执行)向其他节点发送读取摘要请求,都是异步执行,fetchRows,一致性级别为LOCAL_QUORUM或EACH_QUORUM,发送DatacenterReadCallback型的,不执行读修复操作否则发送Re
8、adCallback型的随机计算是否需要进行读修复操作,若执行则向所有备份发送摘要请求,否则向比满足一致性需求的备份数少一的备份发送读取摘要请求。判断受到的回复数量是否满足一致性需求针对每个Command,执行如下操作:如果取出的数据与摘要不匹配,则执行Read Repair操作,从所有节点取得数据,达到要求的数据一致性后返回结果。Readrepair多层调用后将调用RowRepairResolver中的resolve方法,取得每个指定column的最新版本,将区别更新发送给数据过期的备份。否则直接返回结果。,fetchRows(续),MessagingService向指定终端发送消息send
9、RR(MessageProducer producer,InetAddress to,IAsyncCallback cb)接受消息receive(Message message,String id)根据message和id构造MessageDeliveryTask对象根据操作类型构造句柄执行操作如果是读操作则构建ReadVerbHandler对象,执行doVerb(Message message,String id)操作,消息处理服务,从消息中读取命令根据命令中的table名称打开指定Table(代表keyspace,内含ColumnFamilyStore的集合),如果不存在,则初始化包括ca
10、che在内的一系列对象。从存储的rowCache取出值,构造keyCache,调度执行。取出指定Table实例根据命令不同类型构造不同对象执行操作,此处以SliceByNamesReadCommand对象为例调用getRow(Table table)方法取出ColumnFamilyStore取出Row存在rowChache则直接通过key取出ColumnFamily,否则从memtable读取或SSTable中读取,载入cache。发送回复sendReply(reply,id,message.getFrom(),doVerb,构造方法RowCache:列的缓存Cassandra写入数据后会同步
11、更新RowCache,包装Cassandra从RowCache中可以读取到最新的信息。KeyCache:Key的缓存其缓存的是需要读取的数据在SSTable Data文件中的具体位置构造keyCache和rowCache对象keyCache:ConcurrentLinkedHashCache(最大并发64)rowCache:可由配置文件指定取出keyCache中缓存的key从指定存储Cache的路径中读入缓存key结合缓存的key批量打开存储指定columnFamily的SSTable并进行载入处理压缩处理二级索引,ColumnFamilyStore,根据硬件可用处理器的数量创建线程池批量打开
12、SSTable构造SSTableReader对象open(Descriptor descriptor,Set components,Set savedKeys,DataTracker tracker,CFMetaData metadata,IPartitioner partitioner)载入SSTableReader对象load(boolean recreatebloom,Set keysToLoadInCache)throws IOExceptionkeyCache如果容量不够则扩充从名称类“Index.db”的索引文件中加载keycache,batchOpen,rowCacheSaveI
13、nSeconds每隔多长时间将cache写入持久化Cache文件,默认0keyCacheSaveInSeconds每隔多长时间将cache写入持久化Cache文件,默认4hrowCacheKeysToSave每次写入多少个row到持久化Cache文件,默认为整数的最大值rowCacheSize默认为0,缓存Cache的条数keyCacheSize内存最大缓存key的个数,默认为0.01,大于1时是key个数,小于1是百分比,预计总数的百分比。,Cache 参数配置意义,rowCache是存储于JVM的堆中的,不受compaction和read repair操作影响。但是相比于操作系统的page
14、 cache,row cache不是非常高效。而操作系统的page cache会受compaction和read repair操作影响,因此如果依靠page cache在内存中保存动态集,会有很明显的性能降低。使用KeyCache花费的时间相比于它节省的时间是不值一提的,因此将所有key缓存也是可取的。使用rowCache可以节省更多的时间,但是其必须缓存row中的全部数据,是极度消耗内存空间的当有hot row 或static row时,推荐使用row cache存储Cache文件将会极大提升冷启动的速度,花费相对较小,而rowCache存储相对来说就比较昂贵,因此限制使用。,Cache使用
15、建议(wiki),ReadRepair机制Cache实现keyCache使用ConcurrentLinkedHashCache实现,其有最大并发64的限制。(消耗虚拟机内存)rowCache使用用户指定,SerializingCacheProvider。(消耗系统内存)可以减少垃圾收集(GC)在JVM上的压力,从而提高系统的性能.持久化keyCache时间限制默认4个小时(keyCacheSaveInSeconds)读取单列时会读取整个row,占用带宽(当每行只有一个列时不存在)Compaction_strategy使用的压缩策略,1.0版本新增的LeveledCompactionStrate
16、gy可以提高读取性能(实验结果不明)Memtable Thresholds配置,可能导致读速度变慢的若干因素,Compaction_strategy,默认为SizeTieredSizeTiered,是在1.0之前唯一的压实策略,其会导致很大的I/O操作,长时间会导致文件规模更大,对磁盘的操作产生负面影响,但不影响读写性能。使用此策略,会导致会使用1倍以上的磁盘空间。LeveledCompactionStrategy平整压实策略限制的SSTables大小,一个小的文件大小(默认为5 MB的),使SSTables不继续增长的大小与每个连续的压实。磁盘I/O更均匀和可预见的SSTables是不断被压
17、缩成逐渐变大的水平。在每个级别上,行键合并到非重叠SSTables。这可以提高读取性能,因为Cassandra可以决定在每个级别SSTables检查行的关键数据的存在。,1.0版本新增的Compaction策略,Cassandra1.0新增了基于单个ColumnFamily级别的数据压缩。其可以最大化节点硬盘容量,减少硬盘I/O(特别是对于以读取为主体的工作负载),1.0版本新增的Compression,Hinted Handoff如果Cassandra发现一个节点宕机,就会将发送给宕机节点的数据以HINT形式发送给另外一台Cassandra服务器。接收到HINT数据的Cassandra服务器
18、将数据缓存到系统表空间中,当其发现宕机的Cassandra恢复后,将缓存HINT数据发送给恢复的服务器,完成数据传输后,将缓存的HINT数据从系统表空间中删除。1.0版本改进两方面HINT数据存储更高效协调器节点在为某个无应答的节点存储hint 信息时不再需要等待failure dector标记那个节点已宕机,这意味着运行整个节点的read repair不再是必要的。目前read repair操作仍然需要间歇性启动,只是为了处理由于多台节点同时宕机或永久性失去节点产生的数据丢失。,1.0版本改进的Hinted Handoff,这样read repair操作就不像之前版本那么必要,因此默认的读修
19、复操作可能性从百分之百降低到百分之十。这直接导致了对于使用低于ALL级别的读取操作集群的吞吐量明显提升。,1.0版本改进的Hinted Handoff,Cassandra的数据写入机制,Write,Commitlog由如下两部分构成:保存每一次更新操作的值:记录那些数据已从memtable写入SSTable通过log.header文件中记录的元数据信息,Cassandra可以及时删除不必要的Commitlog文件,减少磁盘占用率,并在Cassandra重启时,加快从Commitlog中恢复数据的速度。如果不允许数据丢失,可以使用周期的方式记录Commitlog,如果写入的数据量非常大,同时可以
20、承担由于机器可能宕机导致的数据丢失的风险,可以使用批量记录的方式记录Commitlog。,Commitlog,数据写入Commitlog后,将缓存在Memtable中Cassandra每一个Memtable只为一个ColumnFamily提供服务。每当有数据进入Memtable中时,会将数据保存到成员变量ColumnFamilies中,并解析这个数据排除重复或是已经过期的数据。当Cassandra需要将Memtable中缓存的数据写入磁盘时,会按照内存中的key的顺序写入Sstable中。使用Memtable的优势在于:将随机IO写变成顺序IO写,降低大量的写操作对存储系统的压力。,Memta
21、ble,Cassandra中的Memtable会缓存客户端写入的数据,当Memtable中缓存的某一个ColumnFamily中的数据或者超过上一次生成SSTable的时间,Cassandra会将Memtable中对应的Column-Family的数据持久化磁盘中,生成一个SSTable.SSTable四个不同组成部分:Filter:快速定位某一个key是否在该SSTable文件中存在。使用BloomFilter(好处:减少占用的存储空间和内存空间,提高查询速度).Index:在其中找到某个key对应的Column值在Data文件中的具体位置,,SSTable,Index文件中保存SSTabl
22、e中所有的key以及该key在Data文件中的位置。如果要寻找某一个key在Data文件中的位置,只需要顺序扫描Index文件即可。注意到Index文件中的key是按照由小到大的顺序写的,为节省空间,做一个缓存优化L将Index文件的key以及该key在Index文件中的位置按照某一个间距保存在内存中。辅以二分查找则可快速定位。Index文件是在生成SSTable时生成的。Cassandra还提供一个叫做KeyCache的缓存,用于缓存上一次查找的key在Data文件中的位置。,SSTable(续),Data文件不仅存储真正的数据,还存储某一个key对应的一些Column的索引信息。在Data
23、文件中,保存三类信息:Key值、ColumnIndex(包括BloomFilter和Index)和ColumnValue的值。值得注意的是,这里使用的Index只会对第一层级的Column建索引,即对标准类型的Column-Family非常有效。当Cassandra重启时,不对Data文件进行特殊处理。Statistics文件用来存储SSTable中包含的Column的个数与Row的大小。,SSTable(续),CassandraServerpublic void insert(ByteBuffer key,ColumnParent column_parent,Column column,Co
24、nsistencyLevel consistency_level)Exception:InvalidRequestExceptionUnavailableExceptionTimedOutException,写操作thrift接口,判断是否对指定ColumnFamily具有写权限,如果没有该权限,则抛出InvalidRequestException异常取得ColumnFamily的元数据构造指定column的RowMutation对象执行doInsert方法,判断对指定Keyspace能否对该一致性级别提供支持通过调度,执行StorageProxy的mutate方法判断该更新是否针对计数器变量
25、,根据结果不同执行不同操作。调用performWrite方法,向终端发送执行数据更新请求,internal_insert,根据命令中的table名称打开指定Table(代表keyspace,内含ColumnFamilyStore的集合),如果不存在,则初始化包括cache在内的一系列对象。打开后从中取得备份策略取得负责指定key的终端节点根据一致性级别不同,创建不同的写请求句柄判断目前活着的节点是否符合一致性要求调用WritePerformer的apply方法调用sendToHintedEndpoints方法,向合适的目标节点发送更新(异步),如果是本地节点或者该节点不可用则本地写入通过Fai
26、lureDetector判断目标节点是否可用,可用发消息,不可用执行Hintoff,performWrite,MessagingService向指定终端发送消息sendRR(MessageProducer producer,InetAddress to,IAsyncCallback cb)接受消息receive(Message message,String id)根据message和id构造MessageDeliveryTask对象根据操作类型构造句柄执行操作如果是写操作则构建RowMutationVerbHandler对象,执行doVerb(Message message,String id
27、)操作,消息处理服务,根据消息构造RowMutation对象确定消息中是否有转发标识,有则将消息转发给本地节点。使rowmutation生效apply()取得table元数据打开指定Table(代表keyspace,内含ColumnFamilyStore的集合),如果不存在,则初始化包括cache在内的一系列对象。在table中是写操作生效,将新行写入与该table相关的commit log中,同时写入column family store的memtable中。锁住读操作写入commitlog和memtable解锁读操作发送回复,sendReply(responseMessage,id,message.getFrom(),doVerb,无同步磁盘操作对写操作进行阻塞不对存储在磁盘上的数据进行修改 不更新索引定期发生的异步操作当Memtable满的时候需要写入到SSTable,因此我们不会有太多只存在于内存的数据.每个给定ColumnFamily的一组临时的SSTable会被合并到一个大的SSTable.此时,临时的SSTable就没有用了,它们会在将来的某个时间点被当作垃圾回收掉.,写操作快速原因分析,
链接地址:https://www.31ppt.com/p-5646817.html