You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+98-25Lines changed: 98 additions & 25 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,19 +5,23 @@
5
5
6
6
## Introduction
7
7
8
-
A high-performance, distributed Snowflake ID generator bundle for Symfony, supporting Redis-based sequence distribution. Designed for scenarios requiring globally unique and high-concurrency IDs.
8
+
A high-performance, distributed Snowflake ID generator bundle for Symfony applications. This bundle implements Twitter's Snowflake algorithm to generate unique, time-ordered, 64-bit IDs for distributed systems. It is designed for scenarios requiring globally unique IDs under high concurrency.
9
9
10
10
## Features
11
11
12
-
- Powered by [godruoyi/php-snowflake](https://github.com/godruoyi/php-snowflake) for 64-bit unique ID generation
13
-
- Supports Redis sequence resolver for enhanced uniqueness under high concurrency
14
-
- Auto-generates WorkerId based on hostname, zero configuration required
15
-
- Compatible with Symfony 6.4/7.1, supports autowiring
16
-
- Easy-to-use service interface for seamless integration
12
+
- Generates 64-bit unique IDs based on [godruoyi/php-snowflake](https://github.com/godruoyi/php-snowflake) library
13
+
- Built-in Redis sequence resolver to ensure uniqueness in high-concurrency environments
14
+
- Auto-generates WorkerId based on hostname for distributed scenario support
15
+
- Zero configuration required for basic usage
16
+
- Fully compatible with Symfony 6.4/7.1+
17
+
- Autowiring support for easy integration with Symfony services
18
+
- Thread-safe ID generation
19
+
- Time-ordered IDs for efficient database indexing
17
20
18
21
## Installation
19
22
20
23
### Requirements
24
+
21
25
- PHP >= 8.1
22
26
- Symfony >= 6.4
23
27
- Redis (recommended for distributed sequence safety)
@@ -43,55 +47,124 @@ return [
43
47
44
48
### 2. Generate a Snowflake ID
45
49
46
-
Inject `Tourze\SnowflakeBundle\Service\Snowflake`into your service or controller, then call `id()`:
50
+
Inject the Snowflake service into your service or controller:
47
51
48
52
```php
53
+
<?php
54
+
55
+
namespace App\Service;
56
+
49
57
use Tourze\SnowflakeBundle\Service\Snowflake;
50
58
51
-
class DemoService
59
+
class ProductService
52
60
{
53
-
public function __construct(private Snowflake $snowflake) {}
61
+
public function __construct(
62
+
private readonly Snowflake $snowflake
63
+
) {
64
+
}
54
65
55
-
public function create(): string
66
+
public function createProduct(): int|string
56
67
{
57
-
return $this->snowflake->id();
68
+
// Generate a unique ID for your new product
69
+
$uniqueId = $this->snowflake->id();
70
+
71
+
// Use the ID in your application logic
72
+
return $uniqueId;
58
73
}
59
74
}
60
75
```
61
76
62
77
## Usage
63
78
64
-
### Service Injection
79
+
### Basic Usage
65
80
66
-
Type-hint `Snowflake` for autowiring.
67
-
68
-
### Generate Unique ID
81
+
Simply inject the Snowflake service and call the `id()` method:
69
82
70
83
```php
71
-
$id = $snowflake->id();
84
+
// Inject via constructor
85
+
public function __construct(private readonly Snowflake $snowflake) {}
86
+
87
+
// Generate a unique ID
88
+
$id = $this->snowflake->id();
72
89
```
73
90
91
+
### ID Format and Structure
92
+
93
+
The generated ID is a 64-bit integer with the following structure:
94
+
95
+
- 41 bits for timestamp (milliseconds since the epoch or custom epoch)
96
+
- 10 bits for worker ID (machine ID)
97
+
- 12 bits for sequence number (per millisecond counter)
98
+
99
+
This structure allows for:
100
+
-~69 years of unique timestamps from custom epoch
101
+
- 1024 different worker IDs
102
+
- 4096 IDs per millisecond per worker
103
+
74
104
### WorkerId Generation
75
105
76
-
Automatically derived from the hostname to avoid conflicts in multi-instance deployments.
106
+
By default, the WorkerId is automatically derived from the hostname using a CRC32 hash modulo operation:
107
+
108
+
```php
109
+
$workerId = crc32(gethostname()) % 32; // Returns a value between 0-31
110
+
```
111
+
112
+
This ensures different server instances generally get different WorkerIds without manual configuration.
113
+
114
+
### Redis-Based Sequence Resolver
77
115
78
-
### Redis Distributed Sequence
116
+
When `snc/redis-bundle` is installed and configured in your application, the Snowflake bundle automatically uses Redis for sequence distribution, which provides:
79
117
80
-
If `snc/redis-bundle` is configured, Redis will be used for sequence distribution to ensure uniqueness under high concurrency.
118
+
- Enhanced uniqueness guarantees under high concurrency
119
+
- Improved resistance to clock drift
120
+
- Better distribution of IDs across multiple instances
81
121
82
122
## Configuration
83
123
84
-
No extra configuration is required for most use cases. For advanced customization, extend `ResolverFactory`.
124
+
For basic usage, no extra configuration is required. The bundle works with sensible defaults.
125
+
126
+
### Advanced Configuration
127
+
128
+
For more advanced scenarios, you may extend the `ResolverFactory` to provide a custom sequence resolver:
129
+
130
+
```php
131
+
<?php
132
+
133
+
namespace App\Service;
134
+
135
+
use Godruoyi\Snowflake\SequenceResolver;
136
+
use Tourze\SnowflakeBundle\Service\ResolverFactory;
137
+
138
+
class CustomResolverFactory extends ResolverFactory
139
+
{
140
+
public function resolver(): SequenceResolver
141
+
{
142
+
// Your custom resolver implementation
143
+
return new YourCustomSequenceResolver();
144
+
}
145
+
}
146
+
```
147
+
148
+
Then register your custom factory in your service configuration.
149
+
150
+
## Best Practices
151
+
152
+
-**Redis in Production**: Always use Redis in production environments for sequence distribution
153
+
-**Clock Synchronization**: Ensure your server clocks are synchronized with NTP
154
+
-**Worker ID Management**: For large distributed deployments, consider implementing a centralized WorkerId assignment mechanism
155
+
-**ID Storage**: Store Snowflake IDs as `BIGINT` in databases (or strings if your DB doesn't support 64-bit integers)
156
+
-**Benchmarking**: Test performance in your environment as high throughput may require tuning
85
157
86
-
## Best Practices & Caveats
158
+
## Potential Pitfalls
87
159
88
-
- It is recommended to enable Redis in production for maximum uniqueness
89
-
- For large-scale distributed deployments, review WorkerId generation to avoid rare conflicts
160
+
-**Clock Moving Backwards**: If server time moves backward due to NTP adjustments, duplicate IDs might be generated
161
+
-**Worker ID Conflicts**: In very large deployments, hostname-based WorkerId generation might lead to conflicts
162
+
-**Performance without Redis**: Without Redis, high concurrency might lead to duplicates under extreme circumstances
90
163
91
164
## Contributing
92
165
93
-
Issues and PRs are welcome. See [GitHub Project](https://github.com/tourze/symfony-snowflake-bundle)
166
+
Issues and pull requests are welcome! Please visit the [GitHub repository](https://github.com/tourze/symfony-snowflake-bundle) to contribute.
94
167
95
168
## License
96
169
97
-
This project is licensed under the MIT License. See [LICENSE](LICENSE)
170
+
This bundle is available under the MIT License. See the [LICENSE](LICENSE) file for more information.
0 commit comments