-
Notifications
You must be signed in to change notification settings - Fork 3.4k
HBASE-23309: Adding the flexibility to ChainWalEntryFilter to filter the whole entry if all cells get filtered #837
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
7e627ff
9faebc9
ce10dc1
1b16c3a
ffb78d3
02fdfec
cd3f767
fec27df
5b28db9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -41,15 +41,16 @@ public abstract class BaseReplicationEndpoint extends AbstractService | |
| public static final String REPLICATION_WALENTRYFILTER_CONFIG_KEY | ||
| = "hbase.replication.source.custom.walentryfilters"; | ||
| protected Context ctx; | ||
| private ReplicationPeer replicationPeer; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why this needs to be a global variable? Seems to be used only on init method. |
||
|
|
||
| @Override | ||
| public void init(Context context) throws IOException { | ||
| this.ctx = context; | ||
|
|
||
| if (this.ctx != null){ | ||
| ReplicationPeer peer = this.ctx.getReplicationPeer(); | ||
| if (peer != null){ | ||
| peer.registerPeerConfigListener(this); | ||
| replicationPeer = this.ctx.getReplicationPeer(); | ||
| if (replicationPeer != null){ | ||
| replicationPeer.registerPeerConfigListener(this); | ||
| } else { | ||
| LOG.warn("Not tracking replication peer config changes for Peer Id " + this.ctx.getPeerId() + | ||
| " because there's no such peer"); | ||
|
|
@@ -91,7 +92,7 @@ public WALEntryFilter getWALEntryfilter() { | |
| } | ||
| } | ||
| } | ||
| return filters.isEmpty() ? null : new ChainWALEntryFilter(filters); | ||
| return filters.isEmpty() ? null : new ChainWALEntryFilter(filters, this.replicationPeer); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there some other way to do this that does not require adding ReplicationPeer to the method signature? Why not create a WALEntryFilter that drops empty cells? Then you can add it to the chain if you want and no further changes are needed. |
||
| } | ||
|
|
||
| /** Returns a WALEntryFilter for checking the scope. Subclasses can | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,6 +27,8 @@ | |
| import org.apache.hadoop.hbase.wal.WAL.Entry; | ||
| import org.apache.yetus.audience.InterfaceAudience; | ||
|
|
||
| import static org.apache.hadoop.hbase.HConstants.HBASE_REPLICATION_WAL_FILTER_EMPTY_ENTRY; | ||
|
|
||
| /** | ||
| * A {@link WALEntryFilter} which contains multiple filters and applies them | ||
| * in chain order | ||
|
|
@@ -36,13 +38,25 @@ public class ChainWALEntryFilter implements WALEntryFilter { | |
|
|
||
| private final WALEntryFilter[] filters; | ||
| private WALCellFilter[] cellFilters; | ||
| private ReplicationPeerConfig peerConfig; | ||
|
|
||
| // To allow the empty entries to get filtered, we want to this optional flag to decide | ||
| // if we want to filter the entries which have no cells or all cells got filtered though WALCellFilter | ||
| private String filterEmptyEntry; | ||
|
|
||
| public ChainWALEntryFilter(WALEntryFilter...filters) { | ||
| this.filters = filters; | ||
| initCellFilters(); | ||
| } | ||
|
|
||
| public ChainWALEntryFilter(List<WALEntryFilter> filters) { | ||
| public ChainWALEntryFilter(List<WALEntryFilter> filters, ReplicationPeer replicationPeer) { | ||
| if (replicationPeer != null) { | ||
| peerConfig = replicationPeer.getPeerConfig(); | ||
| if (peerConfig != null) { | ||
| filterEmptyEntry = peerConfig.getConfiguration().get(HBASE_REPLICATION_WAL_FILTER_EMPTY_ENTRY); | ||
| } | ||
| } | ||
|
|
||
| ArrayList<WALEntryFilter> rawFilters = new ArrayList<>(filters.size()); | ||
| // flatten the chains | ||
| for (WALEntryFilter filter : filters) { | ||
|
|
@@ -68,13 +82,17 @@ public void initCellFilters() { | |
|
|
||
| @Override | ||
| public Entry filter(Entry entry) { | ||
|
|
||
|
sandeepvinayak marked this conversation as resolved.
|
||
| for (WALEntryFilter filter : filters) { | ||
| if (entry == null) { | ||
| return null; | ||
| } | ||
| entry = filter.filter(entry); | ||
| } | ||
| filterCells(entry); | ||
| if (shouldFilterEmptyEntry() && entry != null && entry.getEdit().isEmpty()) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Put this into your own WALEntryFilter. Or, fine if you want to add a WALEntryFilter impl to HBase code that does this. But don't do this here
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @apurtell This is the flexility we want to provide to custom replication endpoint so that every custom replication endpoint doesn't need to re-implement everything what Here is the scenario we want to cover, let's take an example: CustomWALFilter implements WALEntryFilter, WALCellFilter {
@override
public void filter(Entry) {
}
@override
public void filterCell(Entry, Cell){
}
}Custom Replication endpoint set the filters by: ChainWALEntryFilter(filters); \\ new CustomWALFilter() is part of filtersif
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this additional logic would fit better in a built-in filter (one of @apurtell suggestions above). That would not need the extra config property nor changes in BaseRepplicationEndpoint |
||
| return null; | ||
| } | ||
| return entry; | ||
| } | ||
|
|
||
|
|
@@ -94,4 +112,9 @@ private Cell filterCell(Entry entry, Cell cell) { | |
| } | ||
| return cell; | ||
| } | ||
|
|
||
| public boolean shouldFilterEmptyEntry() { | ||
| return (filterEmptyEntry != null | ||
| && filterEmptyEntry.equalsIgnoreCase("true")); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't belong here. You are already changing BaseReplicationEndpoint, put it there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sandeepvinayak Do you plan addressing this comment here? I just saw this before I tried to merge this. Thanks.