540 likes | 642 Views
Secondary Indexing in Phoenix. LA HBase User Group – September 4, 2013 . Jesse Yates HBase Committer Software Engineer. Agenda. https://www.madison.k12.wi.us/calendars. About Other Indexing Frameworks Immutable Indexes Mutable Indexes in Phoenix Mutable Indexing Internals Roadmap.
E N D
Secondary Indexing in Phoenix LA HBase User Group – September 4, 2013 Jesse Yates HBase Committer Software Engineer
Agenda https://www.madison.k12.wi.us/calendars About Other Indexing Frameworks Immutable Indexes Mutable Indexes in Phoenix Mutable Indexing Internals Roadmap LA HUG – Sept 2013
About me • Developer at Salesforce • System of Record, Phoenix • Open Source • Phoenix • HBase • Accumulo LA HUG – Sept 2013
Phoenix • Open Source • https://github.com/forcedotcom/phoenix • “SQL-skin” on HBase • Everyone knows SQL! • JDBC Driver • Plug-and-play • Faster than HBase • in some cases LA HUG – Sept 2013
Why Index? HBase is only sorted on 1 “axis” Great for search via a single pattern Example! LA HUG – Sept 2013
Example name: type: subtype: date: major: minor: quantity: LA HUG – Sept 2013
Secondary Indexes Sort on ‘orthogonal’ axis Save full-table scan Expected database feature Hard in HBase b/c of ACID considerations LA HUG – Sept 2013
Agenda About Other Indexing Frameworks Immutable Indexes Mutable Indexes in Phoenix Mutable Indexing Internals Roadmap LA HUG – Sept 2013
http://www.wired.com/wiredenterprise/2011/10/microsoft-and-hadoop/http://www.wired.com/wiredenterprise/2011/10/microsoft-and-hadoop/ LA HUG – Sept 2013
Other (Major) Indexing Frameworks • HBase SEP • Side-Effects Processor • Replication-based • https://github.com/NGDATA/hbase-sep • Huawei • Server-local indexes • Buddy regions • https://github.com/Huawei-Hadoop/hindex LA HUG – Sept 2013
Agenda About Other Indexing Frameworks Immutable Indexes Mutable Indexes in Phoenix Mutable Indexing Internals Roadmap LA HUG – Sept 2013
Immutable Indexes Immutable Rows Much easier to implement Client-managed Bulk-loadable LA HUG – Sept 2013
Bulk Loading phoenix-hbase.blogspot.com LA HUG – Sept 2013
Index Bulk Loading Identity Mapper Custom Phoenix Reducer HFile Output Format LA HUG – Sept 2013
Index Bulk Loading PreparedStatement statement = conn.prepareStatement(dmlStatement); statement.execute(); String upsertStmt = "upsert into core.entity_history(organization_id,key_prefix,entity_history_id, created_by, created_date)\n" + "values(?,?,?,?,?)"; statement = conn.prepareStatement(upsertStmt); … //set values Iterator<Pair<byte[],List<KeyValue>>> dataIterator = PhoenixRuntime.getUncommittedDataIterator(conn); LA HUG – Sept 2013
Agenda About Other Indexing Frameworks Immutable Indexes Mutable Indexes in Phoenix Mutable Indexing Internals Roadmap LA HUG – Sept 2013
The “fun” stuff… LA HUG – Sept 2013
1.5 years LA HUG – Sept 2013
Mutable Indexes • Global Index • Change row state • Common use-case • “expected” implementation • Covered Columns LA HUG – Sept 2013
Usage Just SQL! Baby name popularity Mock demo LA HUG – Sept 2013
Usage Selects the most popular name for a given year SELECT name,occurrences FROM baby_names WHERE year=2012 LIMIT 1; Selects the total occurrences of a given name across all years SELECT /*+ NO_INDEX */ name,sum(occurrences) FROM baby_names WHERE name='Jesse' GROUP BY name; Selects the total occurrences of a given name across all years allowing an index to be used SELECT name,sum(occurrences) FROM baby_names WHERE name='Jesse' GROUP BY NAME; LA HUG – Sept 2013
Usage • Update rows due to census inaccuracy • Will only work if the mutable indexing is working UPSERT INTO baby_names SELECT year,occurrences+3000,sex,name FROM baby_names WHERE name='Jesse'; • Selects the now updated data (from the index table) SELECT name,sum(occurrences) FROM baby_names WHERE name='Jesse' GROUP BY NAME; • Index table still used in scans EXPLAIN SELECT name,sum(occurrences) FROM baby_names WHERE name='Jesse' GROUP BY NAME; LA HUG – Sept 2013
Agenda About Other Indexing Frameworks Immutable Indexes Mutable Indexes in Phoenix Mutable Indexing Internals Roadmap LA HUG – Sept 2013
Internals • Index Management • Build index updates • Ensures index is ‘cleaned up’ • Recovery Mechanism • Ensures index updates are “ACID” LA HUG – Sept 2013
“There is no magic” - Every programming hipster (chipster) LA HUG – Sept 2013
Mutable Indexing: Standard Write Path Client HRegion RegionCoprocessorHost WAL RegionCoprocessorHost MemStore LA HUG – Sept 2013
Mutable Indexing: Standard Write Path Client HRegion RegionCoprocessorHost WAL RegionCoprocessorHost MemStore LA HUG – Sept 2013
Mutable Indexing Indexer Region Coprocessor Host Builder Codec WAL Updater WAL Durable! Index Table Indexer Region Coprocessor Host Index Table Index Table LA HUG – Sept 2013
Index Management public interface IndexBuilder{ public void setup(RegionCoprocessorEnvironmentenv); public Map<Mutation, String> getIndexUpdate(Put put); public Map<Mutation, String> getIndexUpdate(Deletedelete); } Lives within a RegionCoprocesorObserver Access to the local HRegion Specifies the mutations to apply to the index tables LA HUG – Sept 2013
Why not write my own? • Managing Cleanup • Efficient point-in-time correctness • Performance tricks • Abstract access to HRegion • Minimal network hops • Sorting correctness • Phoenix typing ensures correct index sorting LA HUG – Sept 2013
Example: Managing Cleanup • Updates can arrive out of order • Client-managed timestamps LA HUG – Sept 2013
Example: Managing Cleanup Index Table LA HUG – Sept 2013
Example: Managing Cleanup LA HUG – Sept 2013
Example: Managing Cleanup LA HUG – Sept 2013
Example: Managing Cleanup LA HUG – Sept 2013
Example: Managing Cleanup LA HUG – Sept 2013
Managing Cleanup History “roll up” Out-of-order Updates Point-in-time correctness Multiple Timestamps per Mutation Delete vs. DeleteColumn vs. DeleteFamily Surprisingly hard! LA HUG – Sept 2013
Phoenix Index Builder public interfaceIndexCodec{ public void initialize(RegionCoprocessorEnvironmentenv); public Iterable<IndexUpdate> getIndexDeletes(TableState state; public Iterable<IndexUpdate> getIndexUpserts(TableState state); } Much simpler than full index management Hides cleanup considerations Abstracted access to local state LA HUG – Sept 2013
Phoenix Index Codec LA HUG – Sept 2013
Dude, where’s my data? Ensuring Correctness LA HUG – Sept 2013
HBase ACID • Does NOT give you: • Cross-row consistency • Cross-table consistency • Does give you: • Durable data on success • Visibility on success without partial rows LA HUG – Sept 2013
Key Observation “Secondary indexing is inherently an easier problem than full transactions… secondary index updates are idempotent.” - Lars Hofhansl LA HUG – Sept 2013
Idempotent Index Updates • Doesn’t need full transactions • Replay as many times as needed • Can tolerate a little lag • As long as we get the order right LA HUG – Sept 2013
Failure Recovery • <property> • <name>hbase.regionserver.wal.codec</name> <value>o.a.h.hbase.regionserver.wal.IndexedWALEditCodec</value> • </property> • <property> • <name>hbase.regionserver.hlog.reader.impl</name> • <value>o.a.h.hbase.regionserver.wal.IndexedHLogReader</value> • </property> • Custom WALEditCodec • Encodes index updates • Supports compressed WAL • Custom WAL Reader • Replay index updates from WAL LA HUG – Sept 2013
Failure Situations Any time before WAL, client replay Any time after WAL, HBase replay All-or-nothing LA HUG – Sept 2013
Failure #1: Before WAL Client HRegion RegionCoprocessorHost WAL RegionCoprocessorHost MemStore LA HUG – Sept 2013
Failure #1: Before WAL Client HRegion RegionCoprocessorHost WAL No problem! No data is stored in the WAL, client just retries entire update. RegionCoprocessorHost MemStore LA HUG – Sept 2013
Failure #2: After WAL Client HRegion RegionCoprocessorHost WAL RegionCoprocessorHost MemStore LA HUG – Sept 2013
Failure #2: After WAL Client HRegion RegionCoprocessorHost WAL WAL replayed via usual replay mechanisms RegionCoprocessorHost MemStore LA HUG – Sept 2013
Agenda About Other Indexing Frameworks Immutable Indexes Mutable Indexes Roadmap LA HUG – Sept 2013