Skip to content

Commit

Permalink
Merge branch 'master' into gunaprsd-patch-2
Browse files Browse the repository at this point in the history
  • Loading branch information
gunaprsd committed Jan 18, 2019
2 parents 4096418 + 01e4edf commit e8c050e
Show file tree
Hide file tree
Showing 15 changed files with 64 additions and 54 deletions.
13 changes: 13 additions & 0 deletions CONTRIBUTING.md
@@ -0,0 +1,13 @@
# Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
16 changes: 15 additions & 1 deletion README.md
Expand Up @@ -15,7 +15,7 @@ The following features of FASTER differentiate it from a technical perspective:
1. Latch-free cache-optimized index.
2. Unique “hybrid record log” design that combines a traditional persistent append-only log with in-place updates, to shape the memory working set and retain performance.
3. Architecture as a component that can be embedded in multi-threaded cloud apps.
4. Asynchronous recovery model based on group commit.
4. **NEW**: Asynchronous recovery model based on group commit (called [CPR](#Recovery-in-FASTER)).

For standard benchmarks where the working set fits in main memory, we found FASTER to achieve
significantly higher throughput than current systems, and match or exceed the performance of pure
Expand All @@ -36,6 +36,20 @@ For C#, click [here](https://github.com/Microsoft/FASTER/tree/master/cs).

For C++, click [here](https://github.com/Microsoft/FASTER/tree/master/cc).

# Recovery in FASTER

Both the C# and C++ version of FASTER support asynchronous checkpointing and recovery, based on a new
recovery model called Concurrent Prefix Recovery (CPR for short). You can read more about CPR in our research
paper [here](https://www.microsoft.com/en-us/research/uploads/prod/2019/01/cpr-sigmod19.pdf) (to appear in
SIGMOD 2019). Briefly, CPR is based on (periodic) group commit. However, instead of using an expensive
write-ahead log (WAL) which can kill FASTER's high performance, CPR: (1) provides a semantic description of committed
operations, of the form “all operations until offset Ti in session i”; and (2) uses asynchronous
incremental checkpointing instead of a WAL to implement group commit in a scalable bottleneck-free manner.

CPR is available in the C# and C++ versions of FASTER. More documentation on recovery in the C# version is
[here](https://github.com/Microsoft/FASTER/tree/master/cs#checkpointing-and-recovery). For C++, we only
have examples in code right now. The sum-store, located [here](https://github.com/Microsoft/FASTER/tree/master/cc/playground/sum_store-dir), is a good example of checkpointing and recovery.

# Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a
Expand Down
3 changes: 1 addition & 2 deletions cs/README.md
Expand Up @@ -7,7 +7,6 @@ Table of Contents
-----------
* [Getting FASTER](#getting-faster)
* [Basic Concepts](#basic-concepts)
* [Features](#features)
* [Quick End-to-End Sample](#quick-end-to-end-sample)
* [More Examples](#more-examples)
* [Checkpointing and Recovery](#checkpointing-and-recovery)
Expand Down Expand Up @@ -214,4 +213,4 @@ public class RecoveryExample
}
```

FASTER supports two notions of checkpointing: Snapshot and Fold-Over. The former is a full snapshot of in-memory into a separate snapshot file, whereas the latter is an incremental checkpoint of the changes since the last checkpoint. Fold-Over effectively moves the read-only marker of the hybrid log to the tail, and thus all the data is persisted as part of the same hybrid log (there is no separate snapshot file). All subsequent updates are written to new hybrid log tail locations, which gives it its incremental nature. You can find checkpointing examples [here](https://github.com/Microsoft/FASTER/blob/master/cs/test/SimpleRecoveryTest.cs) and [here](https://github.com/Microsoft/FASTER/tree/master/cs/playground/SumStore).
FASTER supports two notions of checkpointing: Snapshot and Fold-Over. The former is a full snapshot of in-memory into a separate snapshot file, whereas the latter is an _incremental_ checkpoint of the changes since the last checkpoint. Fold-Over effectively moves the read-only marker of the hybrid log to the tail, and thus all the data is persisted as part of the same hybrid log (there is no separate snapshot file). All subsequent updates are written to new hybrid log tail locations, which gives Fold-Over its incremental nature. You can find a few basic checkpointing examples [here](https://github.com/Microsoft/FASTER/blob/master/cs/test/SimpleRecoveryTest.cs) and [here](https://github.com/Microsoft/FASTER/tree/master/cs/playground/SumStore). We plan to add more examples and details going forward.
4 changes: 2 additions & 2 deletions cs/playground/ClassCache/Program.cs
Expand Up @@ -18,8 +18,8 @@ static void Main(string[] args)
{
var context = default(CacheContext);

var log = Devices.CreateLogDevice(Path.GetTempPath() + "hybridlog");
var objlog = Devices.CreateObjectLogDevice(Path.GetTempPath() + "hybridlog");
var log = Devices.CreateLogDevice(Path.GetTempPath() + "hlog.log");
var objlog = Devices.CreateLogDevice(Path.GetTempPath() + "hlog.obj.log");
var h = new FasterKV
<CacheKey, CacheValue, CacheInput, CacheOutput, CacheContext, CacheFunctions>(
1L << 20, new CacheFunctions(),
Expand Down
4 changes: 2 additions & 2 deletions cs/playground/ClassSample/Program.cs
Expand Up @@ -134,8 +134,8 @@ class Program
{
static void Main(string[] args)
{
var log = Devices.CreateLogDevice(Path.GetTempPath() + "hybridlog");
var objlog = Devices.CreateObjectLogDevice(Path.GetTempPath() + "hybridlog");
var log = Devices.CreateLogDevice(Path.GetTempPath() + "hlog.log");
var objlog = Devices.CreateLogDevice(Path.GetTempPath() + "hlog.obj.log");

var h = new FasterKV
<MyKey, MyValue, MyInput, MyOutput, MyContext, MyFunctions>
Expand Down
4 changes: 2 additions & 2 deletions cs/playground/MixedSample/Program.cs
Expand Up @@ -134,8 +134,8 @@ class Program
{
static void Main(string[] args)
{
var log = Devices.CreateLogDevice(Path.GetTempPath() + "hybridlog");
var objlog = Devices.CreateObjectLogDevice(Path.GetTempPath() + "hybridlog");
var log = Devices.CreateLogDevice(Path.GetTempPath() + "hlog.log");
var objlog = Devices.CreateLogDevice(Path.GetTempPath() + "hlog.obj.log");

var h = new FasterKV
<MyKey, MyValue, MyInput, MyOutput, MyContext, MyFunctions>
Expand Down
33 changes: 5 additions & 28 deletions cs/src/core/Device/Devices.cs
Expand Up @@ -24,43 +24,20 @@ public static class Devices
/// <returns>Device instance</returns>
public static IDevice CreateLogDevice(string logPath, bool preallocateFile = true, bool deleteOnClose = false)
{
IDevice logDevice = new NullDevice();
if (string.IsNullOrWhiteSpace(logPath))
return logDevice;
#if DOTNETCORE
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
logDevice = new ManagedLocalStorageDevice(logPath + ".log", preallocateFile, deleteOnClose);
}
else
#endif
{
logDevice = new LocalStorageDevice(logPath + ".log", preallocateFile, deleteOnClose);
}
return logDevice;
}
return new NullDevice();

IDevice logDevice;

/// <summary>
/// Create a storage device for the object log (for non-blittable objects)
/// </summary>
/// <param name="logPath">Path to file that will store the log (empty for null device)</param>
/// <param name="preallocateFile">Whether we try to preallocate the file on creation</param>
/// <param name="deleteOnClose">Delete files on close</param>
/// <returns>Device instance</returns>
public static IDevice CreateObjectLogDevice(string logPath, bool preallocateFile = true, bool deleteOnClose = false)
{
IDevice logDevice = new NullDevice();
if (String.IsNullOrWhiteSpace(logPath))
return logDevice;
#if DOTNETCORE
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
logDevice = new ManagedLocalStorageDevice(logPath + ".obj.log", preallocateFile, deleteOnClose);
logDevice = new ManagedLocalStorageDevice(logPath, preallocateFile, deleteOnClose);
}
else
#endif
{
logDevice = new LocalStorageDevice(logPath + ".obj.log", preallocateFile, deleteOnClose);
logDevice = new LocalStorageDevice(logPath, preallocateFile, deleteOnClose);
}
return logDevice;
}
Expand Down
13 changes: 10 additions & 3 deletions cs/src/core/Index/Common/Contexts.cs
Expand Up @@ -117,8 +117,6 @@ public DirectoryConfiguration(string checkpointDir)
public const string cpr_base_folder = "cpr-checkpoints";
public const string cpr_meta_file = "info";

public const string hlog_file = "lss.log";

public void CreateIndexCheckpointFolder(Guid token)
{
var directory = GetIndexCheckpointFolder(token);
Expand Down Expand Up @@ -186,7 +184,16 @@ public string GetHybridLogCheckpointContextFileName(Guid checkpointToken, Guid s
}
public string GetHybridLogCheckpointFileName(Guid token)
{
return String.Format("{0}\\{1}\\{2}\\{3}.dat",
return String.Format("{0}\\{1}\\{2}\\{3}.log",
checkpointDir,
cpr_base_folder,
token,
snapshot_file);
}

public string GetHybridLogObjectCheckpointFileName(Guid token)
{
return String.Format("{0}\\{1}\\{2}\\{3}.obj.log",
checkpointDir,
cpr_base_folder,
token,
Expand Down
4 changes: 2 additions & 2 deletions cs/src/core/Index/FASTER/Checkpoint.cs
Expand Up @@ -290,8 +290,8 @@ private bool GlobalMoveToNextState(SystemState currentState, SystemState nextSta

_hybridLogCheckpoint.snapshotFileDevice = Devices.CreateLogDevice
(directoryConfiguration.GetHybridLogCheckpointFileName(_hybridLogCheckpointToken), false);
_hybridLogCheckpoint.snapshotFileObjectLogDevice = Devices.CreateObjectLogDevice
(directoryConfiguration.GetHybridLogCheckpointFileName(_hybridLogCheckpointToken), false);
_hybridLogCheckpoint.snapshotFileObjectLogDevice = Devices.CreateLogDevice
(directoryConfiguration.GetHybridLogObjectCheckpointFileName(_hybridLogCheckpointToken), false);
_hybridLogCheckpoint.snapshotFileDevice.Initialize(hlog.GetSegmentSize());
_hybridLogCheckpoint.snapshotFileObjectLogDevice.Initialize(hlog.GetSegmentSize());

Expand Down
2 changes: 1 addition & 1 deletion cs/src/core/Index/FASTER/Recovery.cs
Expand Up @@ -247,7 +247,7 @@ private void RestoreHybridLog(long untilAddress)
// By default first page has one extra record
var capacity = hlog.GetCapacityNumPages();
var recoveryDevice = Devices.CreateLogDevice(directoryConfiguration.GetHybridLogCheckpointFileName(recoveryInfo.guid), false);
var objectLogRecoveryDevice = Devices.CreateObjectLogDevice(directoryConfiguration.GetHybridLogCheckpointFileName(recoveryInfo.guid), false);
var objectLogRecoveryDevice = Devices.CreateLogDevice(directoryConfiguration.GetHybridLogObjectCheckpointFileName(recoveryInfo.guid), false);
recoveryDevice.Initialize(hlog.GetSegmentSize());
objectLogRecoveryDevice.Initialize(hlog.GetSegmentSize());
var recoveryStatus = new RecoveryStatus(capacity, startPage, endPage)
Expand Down
2 changes: 1 addition & 1 deletion cs/test/BasicFASTERTests.cs
Expand Up @@ -23,7 +23,7 @@ internal class BasicFASTERTests
[SetUp]
public void Setup()
{
log = Devices.CreateLogDevice(TestContext.CurrentContext.TestDirectory + "\\hybridlog_native.log", deleteOnClose: true);
log = Devices.CreateLogDevice(TestContext.CurrentContext.TestDirectory + "\\hlog1.log", deleteOnClose: true);
fht = new FasterKV<KeyStruct, ValueStruct, InputStruct, OutputStruct, Empty, Functions>
(128, new Functions(), new LogSettings { LogDevice = log, MemorySizeBits = 29 });
fht.StartSession();
Expand Down
8 changes: 4 additions & 4 deletions cs/test/LargeObjectTests.cs
Expand Up @@ -27,8 +27,8 @@ public void LargeObjectTest1()
MyInput input = default(MyInput);
MyLargeOutput output = new MyLargeOutput();

log = Devices.CreateLogDevice(TestContext.CurrentContext.TestDirectory + "\\hlog", deleteOnClose: true);
objlog = Devices.CreateObjectLogDevice(TestContext.CurrentContext.TestDirectory + "\\hlog", deleteOnClose: true);
log = Devices.CreateLogDevice(TestContext.CurrentContext.TestDirectory + "\\hlog.log", deleteOnClose: true);
objlog = Devices.CreateLogDevice(TestContext.CurrentContext.TestDirectory + "\\hlog.obj.log", deleteOnClose: true);

Directory.CreateDirectory(TestContext.CurrentContext.TestDirectory + "\\checkpoints");

Expand Down Expand Up @@ -93,8 +93,8 @@ public void LargeObjectTest2()
MyInput input = default(MyInput);
MyLargeOutput output = new MyLargeOutput();

log = Devices.CreateLogDevice(TestContext.CurrentContext.TestDirectory + "\\hlog", deleteOnClose: true);
objlog = Devices.CreateObjectLogDevice(TestContext.CurrentContext.TestDirectory + "\\hlog", deleteOnClose: true);
log = Devices.CreateLogDevice(TestContext.CurrentContext.TestDirectory + "\\hlog.log", deleteOnClose: true);
objlog = Devices.CreateLogDevice(TestContext.CurrentContext.TestDirectory + "\\hlog.obj.log", deleteOnClose: true);

Directory.CreateDirectory(TestContext.CurrentContext.TestDirectory + "\\checkpoints");

Expand Down
4 changes: 2 additions & 2 deletions cs/test/MiscFASTERTests.cs
Expand Up @@ -23,8 +23,8 @@ internal class MiscFASTERTests
[SetUp]
public void Setup()
{
log = Devices.CreateLogDevice(TestContext.CurrentContext.TestDirectory + "\\hlog2", deleteOnClose: true);
objlog = Devices.CreateObjectLogDevice(TestContext.CurrentContext.TestDirectory + "\\hlog2", deleteOnClose: true);
log = Devices.CreateLogDevice(TestContext.CurrentContext.TestDirectory + "\\hlog2.log", deleteOnClose: true);
objlog = Devices.CreateLogDevice(TestContext.CurrentContext.TestDirectory + "\\hlog2.obj.log", deleteOnClose: true);

fht = new FasterKV<int, MyValue, MyInput, MyOutput, Empty, MixedFunctions>
(128, new MixedFunctions(),
Expand Down
4 changes: 2 additions & 2 deletions cs/test/ObjectFASTERTests.cs
Expand Up @@ -23,8 +23,8 @@ internal class ObjectFASTERTests
[SetUp]
public void Setup()
{
log = Devices.CreateLogDevice(TestContext.CurrentContext.TestDirectory + "\\hlog2", deleteOnClose: true);
objlog = Devices.CreateObjectLogDevice(TestContext.CurrentContext.TestDirectory + "\\hlog2", deleteOnClose: true);
log = Devices.CreateLogDevice(TestContext.CurrentContext.TestDirectory + "\\hlog2.log", deleteOnClose: true);
objlog = Devices.CreateLogDevice(TestContext.CurrentContext.TestDirectory + "\\hlog2.obj.log", deleteOnClose: true);

fht = new FasterKV<MyKey, MyValue, MyInput, MyOutput, Empty, MyFunctions>
(128, new MyFunctions(),
Expand Down
4 changes: 2 additions & 2 deletions cs/test/ObjectRecoveryTest.cs
Expand Up @@ -40,8 +40,8 @@ public void Setup()
Directory.CreateDirectory(test_path);
}

log = Devices.CreateLogDevice(test_path + "\\ort1hlog", false);
objlog = Devices.CreateObjectLogDevice(test_path + "\\ort1hlog", false);
log = Devices.CreateLogDevice(test_path + "\\ort1hlog.log", false);
objlog = Devices.CreateLogDevice(test_path + "\\ort1hlog.obj.log", false);

fht = new FasterKV<AdId, NumClicks, Input, Output, Empty, Functions>
(
Expand Down

0 comments on commit e8c050e

Please sign in to comment.