Skip to content

Commit

Permalink
HADOOP-17928. Syncable: S3A to warn and downgrade (#3585)
Browse files Browse the repository at this point in the history
This switches the default behavior of S3A output streams
to warning that Syncable.hsync() or hflush() have been
called; it's not considered an error unless the defaults
are overridden.

This avoids breaking applications which call the APIs,
at the risk of people trying to use S3 as a safe store
of streamed data (HBase WALs, audit logs etc).

Contributed by Steve Loughran.

Change-Id: I0a02ec1e622343619f147f94158c18928a73a885
  • Loading branch information
steveloughran committed Nov 4, 2021
1 parent 4d04efb commit a68671e
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2188,7 +2188,16 @@
</description>
</property>

<!-- Azure file system properties -->
<property>
<name>fs.s3a.downgrade.syncable.exceptions</name>
<value>true</value>
<description>
Warn but continue when applications use Syncable.hsync when writing
to S3A.
</description>
</property>

<!-- Azure file system properties -->
<property>
<name>fs.AbstractFileSystem.wasb.impl</name>
<value>org.apache.hadoop.fs.azure.Wasb</value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ private Constants() {
* Value: {@value}.
*/
public static final boolean DOWNGRADE_SYNCABLE_EXCEPTIONS_DEFAULT =
false;
true;

/**
* The capacity of executor queues for operations other than block
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -924,30 +924,48 @@ connector isn't saving any data at all. The `Syncable` API, especially the
`hsync()` call, are critical for applications such as HBase to safely
persist data.

The S3A connector throws an `UnsupportedOperationException` when these API calls
are made, because the guarantees absolutely cannot be met: nothing is being flushed
or saved.
When configured to do so, the S3A connector throws an `UnsupportedOperationException`
when these API calls are made, because the API guarantees absolutely cannot be met:
_nothing is being flushed or saved_.

* Applications which intend to invoke the Syncable APIs call `hasCapability("hsync")` on
* Applications which intend to invoke the Syncable APIs should call `hasCapability("hsync")` on
the stream to see if they are supported.
* Or catch and downgrade `UnsupportedOperationException`.

These recommendations _apply to all filesystems_.
These recommendations _apply to all filesystems_.

To downgrade the S3A connector to simply warning of the use of
For consistency with other filesystems, S3A output streams
do not by default reject the `Syncable` calls -instead
they print a warning of its use.


The count of invocations of the two APIs are collected in the S3A filesystem
Statistics/IOStatistics and so their use can be monitored.

To switch the S3A connector to rejecting all use of
`hsync()` or `hflush()` calls, set the option
`fs.s3a.downgrade.syncable.exceptions` to true.
`fs.s3a.downgrade.syncable.exceptions` to `false`.

```xml
<property>
<name>fs.s3a.downgrade.syncable.exceptions</name>
<value>true</value>
<value>false</value>
</property>
```

The count of invocations of the two APIs are collected
in the S3A filesystem Statistics/IOStatistics and so
their use can be monitored.
Regardless of the setting, the `Syncable` API calls do not work.
Telling the store to *not* downgrade the calls is a way to
1. Prevent applications which require Syncable to work from being deployed
against S3.
2. Identify applications which are making the calls even though they don't
need to. These applications can then be fixed -something which may take
time.

Put differently: it is safest to disable downgrading syncable exceptions.
However, enabling the downgrade stops applications unintentionally using the API
from breaking.

*Tip*: try turning it on in staging environments to see what breaks.

### `RemoteFileChangedException` and read-during-overwrite

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ public void testCallingCloseAfterCallingAbort() throws Exception {
*/
@Test
public void testSyncableUnsupported() throws Exception {
final S3ABlockOutputStream.BlockOutputStreamBuilder
builder = mockS3ABuilder();
builder.withDowngradeSyncableExceptions(false);
stream = spy(new S3ABlockOutputStream(builder));
intercept(UnsupportedOperationException.class, () -> stream.hflush());
intercept(UnsupportedOperationException.class, () -> stream.hsync());
}
Expand Down

0 comments on commit a68671e

Please sign in to comment.