16
16
load scenarios)
17
17
'''
18
18
19
- def rand_zipf (n , alpha , numSamples ):
19
+ def rand_zipf_generator (n , alpha , count , pipeline ):
20
20
"""
21
21
n: The upper bound of the values to generate a zipfian distribution over
22
22
(n = 30 would generate a distribution of given alpha from values 1 to 30)
23
23
alpha: The alpha parameter to be used while creating the Zipfian distribution
24
24
num_samples: The total number of samples to generate over the Zipfian distribution
25
- returns a list of num_samples values of items in the range [1, n] that follow a
26
- Zipfian distribution.
25
+ This is a generator that yields up to count values using a generator.
27
26
"""
28
27
29
28
# Calculate Zeta values from 1 to n:
@@ -33,48 +32,85 @@ def rand_zipf(n, alpha, numSamples):
33
32
# Store the translation map:
34
33
distMap = [x / zeta [- 1 ] for x in zeta ]
35
34
36
- # Generate an array of uniform 0-1 pseudo-random values:
37
- u = np .random .random (numSamples )
35
+ if pipeline == 0 :
36
+ # Generate an array of uniform 0-1 pseudo-random values:
37
+ u = np .random .random (count )
38
38
39
- # bisect them with distMap
40
- v = np .searchsorted (distMap , u )
39
+ # bisect them with distMap
40
+ v = np .searchsorted (distMap , u )
41
41
42
- samples = [t - 1 for t in v ]
43
- return samples
42
+ samples = [t - 1 for t in v ]
44
43
45
- def update_stats (r , initial_hits , initial_misses , value_index , total_count ):
44
+ for sample in samples :
45
+ yield sample
46
+ else :
47
+ current_count = 0
48
+ while current_count < count :
49
+ # Generate an array of uniform 0-1 pseudo-random values, of the pipeline length:
50
+ u = np .random .random (pipeline )
51
+
52
+ # bisect them with distMap
53
+ v = np .searchsorted (distMap , u )
54
+
55
+ samples = [t - 1 for t in v ]
56
+ yield samples
57
+
58
+ current_count += len (samples )
59
+
60
+ def update_stats (r , hits , misses , value_index , total_count ):
46
61
"""
47
- A void function that uses terminal control sequences to update hit/miss
48
- ratio stats for the user while the testing tool runs.
62
+ A void function that uses terminal control sequences
63
+ to update hit/miss ratio stats for the user
64
+ while the testing tool runs.
49
65
"""
50
66
percent_complete = (value_index + 1 ) / total_count
51
67
52
68
# Use the terminal control sequence to move the cursor to the beginning of the line
53
69
print ("\r " , end = "" )
54
70
55
- current_info = r .info ()
56
- current_hits = current_info ["keyspace_hits" ]
57
- current_misses = current_info ["keyspace_misses" ]
58
-
59
71
# Print the loading bar and current hit rate
60
- print ("[{}{}] {:.0f}%, current hit rate: {:.6f}%" .format ("#" * int (percent_complete * 20 ), " " * int (20 - percent_complete * 20 ), percent_complete * 100 , (current_hits / (current_hits + current_misses )) * 100 ), end = "" )
72
+ print ("[{}{}] {:.0f}%, current hit rate: {:.6f}%" .format ("#" * int (percent_complete * 20 ), " " * int (20 - percent_complete * 20 ), percent_complete * 100 , (hits / (hits + misses )) * 100 ), end = "" )
61
73
62
74
if __name__ == '__main__' :
63
75
parser = argparse .ArgumentParser (description = 'Cache Benchmark' , formatter_class = argparse .ArgumentDefaultsHelpFormatter )
64
76
parser .add_argument ('-c' , '--count' , type = int , default = 100000 , help = 'total number of incrby operations' )
65
77
parser .add_argument ('-u' , '--uri' , type = str , default = 'redis://localhost:6379' , help = 'Redis server URI' )
66
78
parser .add_argument ('-a' , '--alpha' , type = int , default = 1.0 , help = 'alpha value being used for the Zipf distribution' )
67
79
parser .add_argument ('-n' , '--number' , type = int , default = 30 , help = 'the number of values to be used in the distribution' )
80
+ parser .add_argument ('-d' , '--length' , type = int , default = 10 , help = 'the length of the values to be used in the distribution' )
81
+ parser .add_argument ('-p' , '--pipeline' , type = int , default = 0 , help = 'pipeline size' )
82
+
68
83
args = parser .parse_args ()
69
84
uri = urlparse (args .uri )
70
85
71
- r = redis .Redis (host = uri .hostname , port = uri .port )
72
-
73
- initial_hits = r .info ()['keyspace_hits' ]
74
- initial_misses = r .info ()['keyspace_misses' ]
75
-
76
- distribution_values = rand_zipf (args .number , args .alpha , args .count )
77
- for idx , val in enumerate (distribution_values ):
78
- r .incrby (str (val ), 1 )
79
- if idx % 50 == 0 :
80
- update_stats (r , initial_hits , initial_misses , idx , args .count )
86
+ r = redis .StrictRedis (host = uri .hostname , port = uri .port )
87
+
88
+ misses = 0
89
+ hits = 0
90
+
91
+ distribution_values_generator = rand_zipf_generator (args .number , args .alpha , args .count , args .pipeline )
92
+
93
+ if args .pipeline == 0 :
94
+ for idx , val in enumerate (distribution_values_generator ):
95
+ result = r .set (str (val ), 'x' * args .length , nx = True )
96
+ if result :
97
+ misses += 1
98
+ else :
99
+ hits += 1
100
+ if idx % 50 == 0 :
101
+ update_stats (r , hits , misses , idx , args .count )
102
+ else :
103
+ total_count = 0
104
+ for idx , values in enumerate (distribution_values_generator ):
105
+ total_count += len (values )
106
+ p = r .pipeline ()
107
+ for val in values :
108
+ p .set (str (val ), 'x' * args .length , nx = True )
109
+ responses = p .execute ()
110
+ for resp in responses :
111
+ if resp :
112
+ misses += 1
113
+ else :
114
+ hits += 1
115
+ if idx % 20 == 0 :
116
+ update_stats (r , hits , misses , total_count , args .count )
0 commit comments