Merge pull request #36812 from jakub-d/master

Automatic merge from submit-queue

Change ScheduledJob POD name suffix from hash to Unix Epoch

**What this PR does / why we need it**:

There is a bug in a ScheduledJob POD suffix hash function (#34447). If you generate more than ~20 PODs you will start having collisions. Here is the code which proves that:
```
package main

import "fmt"
import "time"
import "hash/adler32"
import hashutil "k8s.io/kubernetes/pkg/util/hash"

func main() {
        start_time, _ := time.Parse("2006-Jan-02", "2016-Nov-14")
        var hits map[uint32]int = make(map[uint32]int)
        fmt.Println("| Date | Epoch | Hash | Hits |")
        fmt.Println("| --------------- | ---------- | --- | ---- |")
        for i:=0; i<30; i++ {
                dt:=start_time.Add(time.Duration(i*5)*time.Minute)
                hdt:=getTimeHash(dt)
                _, ok := hits[hdt]
                if ! ok {
                        hits[hdt]=0
                }
                hits[hdt]++
                fmt.Printf("| %s | %d | %d | %d  |\n",dt.Format(time.Stamp), dt.Unix(), hdt, hits[hdt])
        }
}

func getTimeHash(tm time.Time) uint32 {
        timeHasher := adler32.New()
        hashutil.DeepHashObject(timeHasher, tm)
        return timeHasher.Sum32()
}
```

The ouptut is:

| Date | Epoch | Hash | Hits |
| --------------- | ---------- | --- | ---- |
| Nov 14 00:00:00 | 1479081600 | 4175643772 | 1  |
| Nov 14 00:05:00 | 1479081900 | **4209853567** | 1  |
| Nov 14 00:10:00 | 1479082200 | **4141499513** | 1  |
| Nov 14 00:15:00 | 1479082500 | 4175709308 | 1  |
| Nov 14 00:20:00 | 1479082800 | 4209919103 | 1  |
| Nov 14 00:25:00 | 1479083100 | 4244128898 | 1  |
| Nov 14 00:30:00 | 1479083400 | 4072621171 | 1  |
| Nov 14 00:35:00 | 1479083700 | 4106830966 | 1  |
| Nov 14 00:40:00 | 1479084000 | 4141040761 | 1  |
| Nov 14 00:45:00 | 1479084300 | 4072686707 | 1  |
| Nov 14 00:50:00 | 1479084600 | 4106896502 | 1  |
| Nov 14 00:55:00 | 1479084900 | 4141106297 | 1  |
| Nov 14 01:00:00 | 1479085200 | 4072752243 | 1  |
| Nov 14 01:05:00 | 1479085500 | 4106962038 | 1  |
| Nov 14 01:10:00 | 1479085800 | 4141171833 | 1  |
| Nov 14 01:15:00 | 1479086100 | 4175381628 | 1  |
| Nov 14 01:20:00 | 1479086400 | 4107027574 | 1  |
| Nov 14 01:25:00 | 1479086700 | 4141237369 | 1  |
| Nov 14 01:30:00 | 1479087000 | 4175447164 | 1  |
| Nov 14 01:35:00 | 1479087300 | 4107093110 | 1  |
| Nov 14 01:40:00 | 1479087600 | 4141302905 | 1  |
| Nov 14 01:45:00 | 1479087900 | 4175512700 | 1  |
| Nov 14 01:50:00 | 1479088200 | 4107158646 | 1  |
| Nov 14 01:55:00 | 1479088500 | 4141368441 | 1  |
| Nov 14 02:00:00 | 1479088800 | 4175578236 | 1  |
| Nov 14 02:05:00 | 1479089100 | 4209788031 | 1  |
| Nov 14 02:10:00 | 1479089400 | 4141433977 | 1  |
| Nov 14 02:15:00 | 1479089700 | 4175643772 | 2  |
| Nov 14 02:20:00 | 1479090000 | **4209853567** | 2  |
| Nov 14 02:25:00 | 1479090300 | **4141499513** | 2  |

This PR is a proposal to abandon hashes and use Unix Epoch times instead.
Cons:
* It's easy to sort PODs this way
* The length of the Epoch time stamp is the same as the length of the current hash
* As it's epoch - we won't have collisions

**Which issue this PR fixes**
fixes #34447
pull/6/head
Kubernetes Submit Queue 2016-11-15 16:08:55 -08:00 committed by GitHub
commit 0bd5bd60ac
2 changed files with 3 additions and 7 deletions

View File

@ -32,7 +32,6 @@ go_library(
"//pkg/runtime:go_default_library",
"//pkg/types:go_default_library",
"//pkg/util/errors:go_default_library",
"//pkg/util/hash:go_default_library",
"//pkg/util/metrics:go_default_library",
"//pkg/util/runtime:go_default_library",
"//pkg/util/wait:go_default_library",

View File

@ -19,7 +19,6 @@ package cronjob
import (
"encoding/json"
"fmt"
"hash/adler32"
"time"
"github.com/golang/glog"
@ -30,7 +29,6 @@ import (
"k8s.io/kubernetes/pkg/apis/batch"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/types"
hashutil "k8s.io/kubernetes/pkg/util/hash"
)
// Utilities for dealing with Jobs and CronJobs and time.
@ -200,10 +198,9 @@ func getJobFromTemplate(sj *batch.CronJob, scheduledTime time.Time) (*batch.Job,
return job, nil
}
func getTimeHash(scheduledTime time.Time) uint32 {
timeHasher := adler32.New()
hashutil.DeepHashObject(timeHasher, scheduledTime)
return timeHasher.Sum32()
// Return Unix Epoch Time
func getTimeHash(scheduledTime time.Time) int64 {
return scheduledTime.Unix()
}
// makeCreatedByRefJson makes a json string with an object reference for use in "created-by" annotation value